原型范围不起作用

时间:2010-09-30 12:10:08

标签: java spring

我在我的应用程序中创建了一个原型范围的bean,并且我使用setter将其注入另一个bean。但是当我在我的类中使用注入的bean时,它总是每次使用相同的实例而不是新的实例。

以下是代码的快照

<bean name="prototypeScope" Class="A" scope="prototype">
</bean>

<bean Class="Consumer">
    <property name="a" ref="prototypeScope" />
</bean>

public class Consumer{
    privare A a;

    public void setA(A a){
        this.a = a;
    }


    public void consume(){

        a.doSomething();

    }
}

此致

3 个答案:

答案 0 :(得分:6)

这是与原型范围豆相关的常见错误。

只有当我们从应用程序上下文请求bean的副本时才会创建原型范围bean的新实例,而不是每次我们在实例上调用方法时都会创建。

在您的情况下,您使用后者的setter将原型范围的bean注入另一个bean,因此创建第二个类将创建原型范围bean的新实例。但它会使用相同的实例,只要它被你的另一个mannualy替换。

如果您想在特定操作(如方法调用)期间使用原型范围bean的新实例,则必须从应用程序内容中获取该bean的新实例。

例如:

<bean name="prototypeScope" Class="A" scope="prototype">
</bean>

<bean Class="Consumer">
</bean>

Java代码:

public class Consumer implements ApplicationContextAware{
    privare ApplicationContext context;

    public void setApplicationContext(ApplicationContext context){
        this.context = context;
    }


    public void consume(){

        A a = context.getBean("prototypeScope", A.class);

        a.doSomething();

    }
}

在这个例子中,当调用consume方法时,会创建一个新的A类实例。

答案 1 :(得分:2)

有两种主要方法可以解决Singleton-Bean-has-Prototype依赖问题。

一个是紧密耦合到applicationContext,如Ram's answer,另一个是Lookup Method Injection

基本上,你将bean类抽象化并为依赖项添加一个抽象方法,如下所示:

public abstract class MyBean{

    public abstract MyService lookupService();

}

然后添加如下所示的bean定义:

<bean id="myBean" class="fiona.apple.sucks.MyBean">
<!-- sorry, just wanted to insert sucks after Spring's fiona apple example,
didn't think about the connotations :-) -->
    <lookup-method name="lookupService"/>
</bean>

现在,Spring将创建bean类的CGLib子类,每次调用myBean.lookupService()时都会返回一个新的Prototype实例。

答案 2 :(得分:1)

我曾经使用过这样的方法..

首先我声明了一个bean

<bean id="notSingelton" class="com.Foo" singleton="false" />

然后制作了一个界面

public interface FooFactory {
    Foo make(String name);
}

将其包装到ServiceLocatorFactoryBean

<bean id="fooFactory"
     class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
    <property name="serviceLocatorInterface" value="com.FooFactory" />
</bean>

<bean id="consumer" class="com.Consumer">
    <constructor-arg ref="fooFactory" />
</bean>

消费者类看起来像这样:

public class Consumer {
    private FooFactory fooFactory;

    public Consumer(FooFactory fooFactory) {
         this.fooFactory = fooFactory;
    }


    public void consume(){
        Foo foo = fooFactory.make("notSingelton");
        foo.doSomething();
    }
}
相关问题