Java 使用Autowire检索作用域为原型的bean

Java 使用Autowire检索作用域为原型的bean,java,spring,dependency-injection,inversion-of-control,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> 我创建了一个测试类,如下所示: Item soap = service.getItem(ITEM.SOAP); Item soap2 = service.getItem(ITEM.SOAP);

在我的XML配置中,我有:

<bean id="soap" class="org.grocery.item.Soap" scope="prototype">
        <property name="price" value="20.00" />
</bean>
我创建了一个测试类,如下所示:

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对象。然而,它没有,即使soap被声明为范围为原型。这是为什么?

当您创建服务对象时,spring将向您的服务对象注入soap对象的实例。因此,对服务的
getSoap()
的所有调用都将检索创建服务时注入的相同soap对象。

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

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

  • 查找方法:
  • 不要将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实例

  • 作用域代理
  • 这指示Spring注入代理,而不是真正的Soap实例。注入的代理方法将查找正确的soap实例(因为它是一个原型bean,所以是一个新实例)并委托给它们:

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

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

  • 查找方法:
  • 不要将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实例

  • 作用域代理
  • 这指示Spring注入代理,而不是真正的Soap实例。注入的代理方法将查找正确的soap实例(因为它是一个原型bean,所以是一个新实例)并委托给它们:

    <bean id="soap" class="foo.Soap">
      <aop:scoped-proxy/>
    </bean>
    
    
    
    有没有办法告诉它每次调用getSoap都会返回一个新的soap对象?有没有办法告诉它每次调用getSoap都会返回一个新的soap对象?+1表示查找方法方法,但我认为作用域代理方法在这里不起作用
    service.getItem(ITEM.SOAP)
    将返回对代理的引用,这意味着对返回的
    ITEM
    进行的每个方法调用都将生成基础bean的新实例。我不认为这是OP所追求的。我仍然对查找方法有点困惑,我会在xml中声明它吗?如果是的话,怎么做?+1表示查找方法方法,但我认为作用域代理方法在这里不起作用
    service.getItem(ITEM.SOAP)
    将返回对代理的引用,这意味着对返回的
    ITEM
    进行的每个方法调用都将生成基础bean的新实例。我不认为这是OP所追求的。我仍然对查找方法有点困惑,我会在xml中声明它吗?如果是,怎么做?