user962206
user962206

Reputation: 16117

Retrieving beans that are Scoped prototype with Autowire

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

Answers (2)

Jawher
Jawher

Reputation: 7097

Renjith explained the why in his answer. As for the how, I know of 2 ways to achieve this:

  1. lookup method:

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.

  1. Scoped proxies

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

Renjith
Renjith

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

Related Questions