I want to know if this is a bug or it is working as designed.
Yes, I think it is working as designed.
Your testObject
bean is a singleton. That singleton bean only has 1 copy of the map
and testA
properties. The behavior you are describing is exactly what I would expect.
EDIT:
I have reviewed the application in the linked project and this is what is going on...
In resources.groovy
you have something like this:
testObject(TestObject) { bean ->
bean.scope = "prototype"
mapIssue1 = ["key1FromResource.groovy": "value1FromResource.groovy"]
}
That testObject
bean is a prototype scoped bean so each time you retrieve one, you will get a new instance. However, you have the initialization Map
hardcoded in the bean definition so the bean definition that is created has that Map
associated with it so every bean created from that bean def will have the same Map
. If you want a different Map
instance, you could create it in afterPropertiesSet
or similar.
The unit test at https://github.com/rushidesai1/Grails2_4_2_BeanIssue/blob/e9b7c9e70da5863f0716b998462eca60924ee717/test/unit/test/SpringBeansSpec.groovy is not very well written. Seeing what is going on relies on interrogating stdout after all of those printlns. The behavior could be more simply verified with something like this:
resources:groovy
import test.TestObject
beans = {
testObject(TestObject) { bean ->
bean.scope = "prototype"
mapIssue1 = ["key1FromResource.groovy":"value1FromResource.groovy"]
}
}
SpringBeansSpec.groovy
package test
import grails.test.mixin.TestMixin
import grails.test.mixin.support.GrailsUnitTestMixin
import spock.lang.Specification
@TestMixin(GrailsUnitTestMixin)
class SpringBeansSpec extends Specification {
static loadExternalBeans = true
void 'test bean properties'() {
setup:
def testObject1 = grailsApplication.mainContext.testObject
def testObject2 = grailsApplication.mainContext.testObject
expect: 'test TestObject beans are not the same instance'
!testObject1.is(testObject2)
and: 'the TestObject beans share values defined in the bean definition'
testObject1.mapIssue1.is(testObject2.mapIssue1)
}
}
(or any collection tag) we get a new list everytime. If I have to do it in 'afterPropertiesSet' or 'Postconstruct' it defeats purpose of DI.
– rushidesai1 Aug 25 '16 at 18:33(or any collection tag) we get a new list everytime." - That is different than what your sample app is doing. Your sample app isn't defining a `List` or `Map` bean. Your sample app is just creating a `Map`. If you wanted a new one created for each `testObject` bean, you can do that by defining a corresponding `Map` bean and having Spring inject that into the `testObject` beans.
– Jeff Scott Brown Aug 25 '16 at 19:11