Reputation: 16117
In my XML configuration I have this:
<bean id="soap" class="org.grocery.item.Soap" scope="prototype">
<property name="price" value="20.00" />
</bean>
And in my service class I have the "soap" autowired like this:
@Autowired
private Soap soap;
//Accessor methods
And I created a test class like this:
Item soap = service.getItem(ITEM.SOAP);
Item soap2 = service.getItem(ITEM.SOAP);
if(soap2 == soap ){
System.out.println("SAME REFERENCE");
}
And this is my getItem method in my service class:
public Item item(Item enumSelector) {
switch (enumSelector) {
case SOAP:
return this.getSoap();
}
return null;
}
@Autowired
private Soap soap;
//Accessor methods
Now what I am expecting is that the when I call the this.getSoap(); it will return a new Soap object. However, it did not, even though the soap is declared scoped as prototype. Why is that?
Upvotes: 0
Views: 2038
Reputation: 7097
Renjith explained the why in his answer. As for the how, I know of 2 ways to achieve this:
Don't declare the soap dependency as a field, but rather as an abstract getter method:
protected abstract Soap getSoap();
Whenever you need the soap in your service (like in the getItem method), call the getter.
In the xml config, instruct Spring to implement that method for you:
<bean id="service" class="foo.YourService">
<lookup-method name="getSoap" bean="soapBeanId"/>
</bean>
The Spring supplied implementation would fetch a fresh instance of Soap whenever called.
This instructs Spring to inject a proxy instead of the real Soap instance. The injected proxy methods would lookup the correct soap instance (a fresh one since it's a prototype bean) and delegate to them:
<bean id="soap" class="foo.Soap">
<aop:scoped-proxy/>
</bean>
Upvotes: 2
Reputation: 3274
When you create the service object, spring will inject an instance of soap object to your service object.So all the calls to getSoap()
of service will be retrieving the same soap object which was injected when service was created.
Upvotes: 2