【问题标题】:Retrieving beans that are Scoped prototype with Autowire使用 Autowire 检索 Scoped 原型的 bean
【发布时间】:2013-02-20 09:56:34
【问题描述】:

在我的 XML 配置中,我有这个:

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

在我的服务类中,我有这样的“肥皂”自动接线:

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 有没有办法告诉我每次调用getSoap都会返回一个新的soap对象?
    【解决方案2】:

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

    1. 查找方法:

    不要将soap依赖声明为一个字段,而是作为一个抽象的getter方法:

    protected abstract Soap getSoap();
    

    当您需要在服务中使用肥皂时(例如在 getItem 方法中),调用 getter。

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

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

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

    1. 范围代理

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

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

    【讨论】:

    • +1 用于查找方法方法,但我认为范围代理方法在这里不起作用。 service.getItem(ITEM.SOAP) 将返回对代理的引用,这意味着对返回的 Item 进行的每个方法调用都会生成底层 bean 的新实例。我不认为这就是 OP 所追求的。
    • 查找方法我还是有点迷茫,要不要在xml中声明呢?如果有怎么办?
    猜你喜欢
    • 2014-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 2015-01-14
    相关资源
    最近更新 更多