使用Autowire检索作为Scoped原型的bean

时间:2013-02-20 09:56:35

标签: java spring dependency-injection inversion-of-control

在我的XML配置中,我有:

<bean id="soap" class="org.grocery.item.Soap" scope="prototype">
        <property name="price" value="20.00" />
</bean>

在我的服务类中,我有“soap”自动装配:

@Autowired
private Soap soap;
//Accessor methods

我创建了一个这样的测试类:

Item soap = service.getItem(ITEM.SOAP);
Item soap2 = service.getItem(ITEM.SOAP);

if(soap2 == soap ){
    System.out.println("SAME REFERENCE");
}

这是我服务类中的getItem方法:

public Item item(Item enumSelector) {
        switch (enumSelector) {
            case SOAP:
                return this.getSoap();
        }
        return null;
    }

@Autowired
private Soap soap;
//Accessor methods

现在我所期待的是我何时调用this.getSoap();它将返回一个新的Soap对象。然而,它没有,即使肥皂被宣布为原型。那是为什么?

2 个答案:

答案 0 :(得分:2)

当你创建服务对象时,spring会向你的服务对象注入一个soap对象的实例。所以对getSoap()服务的所有调用都将检索在创建服务时注入的同一个soap对象。

答案 1 :(得分:2)

Renjith在他的回答中解释了原因。至于方法,我知道有两种方法可以做到这一点:

  1. 查询方法:
  2. 不要将soap依赖项声明为字段,而是将其声明为抽象getter方法:

    protected abstract Soap getSoap();
    

    每当你需要服务中的soap时(比如在getItem方法中)​​,请调用getter。

    在xml配置中,指示Spring为您实现该方法:

    <bean id="service" class="foo.YourService">
      <lookup-method name="getSoap" bean="soapBeanId"/>
    </bean>
    

    Spring提供的实现将在每次调用时获取一个新的Soap实例。

    1. Scoped proxies
    2. 这指示Spring注入代理而不是真正的Soap实例。注入的代理方法将查找正确的soap实例(一个新的,因为它是一个原型bean)并委托给它们:

      <bean id="soap" class="foo.Soap">
        <aop:scoped-proxy/>
      </bean>