我在我的应用程序中创建了一个原型范围的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();
}
}
此致
答案 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();
}
}