Java Spring原型bean与单例bean和依赖注入相结合。是否存在仅用于配置的方法?
我有一个单例bean,每个函数调用都需要返回对不同(新)原型bean的引用。我能想到的唯一方法是通过调用其getBean()方法,以编程方式从BeanFactory/ApplicationContext检索一个新的原型bean实例。下面是代码示例 有更好的方法吗?希望只能通过配置?(就我个人而言,我怀疑有…)Java Spring原型bean与单例bean和依赖注入相结合。是否存在仅用于配置的方法?,java,spring,Java,Spring,我有一个单例bean,每个函数调用都需要返回对不同(新)原型bean的引用。我能想到的唯一方法是通过调用其getBean()方法,以编程方式从BeanFactory/ApplicationContext检索一个新的原型bean实例。下面是代码示例 有更好的方法吗?希望只能通过配置?(就我个人而言,我怀疑有…) 公共类原型bean{ .... } 公共类单体bean{ 私营豆厂; 公共ProtoBean分发(){ return(ProtoBean)factory.getBean(“ProtoBe
公共类原型bean{
....
}
公共类单体bean{
私营豆厂;
公共ProtoBean分发(){
return(ProtoBean)factory.getBean(“ProtoBean”);
}
....
}
看一看使用方法注入使得单例bean类难以进行单元测试(您需要创建一个子类来实现给出依赖关系的方法)。另外,它的可重用性较差,因为您不能直接实例化它,所以如果您不使用Spring并且想要使用这个类,那么您需要子类化并提供bean返回方法
更好的方法是使用代理、原型目标源和原型目标bean,如下所示。这样的单例bean类很容易进行单元测试,并且具有更好的可重用性
<bean id="targetPooledObject" class="pool.PooledObject" scope="prototype">
<constructor-arg value="42" />
</bean>
<bean id="prototypeTargetSource" class="org.springframework.aop.target.PrototypeTargetSource">
<property name="targetBeanName" value="targetPooledObject" />
</bean>
<bean id="pooledObject" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="targetSource" ref="prototypeTargetSource" />
</bean>
<bean id="poolConsumer" class="pool.PoolConsumer">
<property name="pooledObject" ref="pooledObject" />
</bean>
从Spring3.0开始,我们可以使用
为了简化工作,Spring还为@Scope引入了proxyMode属性,因此我们不仅限于XML声明。例如:
@Scope(value = "prototype", proxyMode = ScopedProxyMode.INTERFACES)
确保清楚地记录注入的bean是一个代理,以警告其他人getClass()和强制转换可能不会产生预期的结果。另外,请确保代理类中的equals()和hashCode()使用访问方法,而不是直接访问类变量。很有趣,但请您详细说明一下(即添加java代码)@Yaneeve添加了代码并稍微修改了配置以反映它。请原谅我的代码不干净。@Yaneeve我们也可以在春天创建一个bean池。使用与上述类似的配置,但使用“CommonsPoolTargetSource”而不是“PrototypeTargetSource”。例如,当以MDB方式通过Spring处理JMS消息时,这可能很有用。下面是一些细节:正如Christopher所说,这个答案已经过时了,因为Spring3.0中的
元素是正确的方法。此外,正如shrini1000所指出的,方法注入使类难以测试。
public class PooledObject
{
private int x;
public PooledObject(int x)
{
this.x = x;
}
public void foo()
{
System.out.println("foo called");
}
}
public class PoolConsumer
{
private PooledObject pooledObject;
public PooledObject getPooledObject()
{
return pooledObject;
}
public void setPooledObject(PooledObject pooledObject)
{
this.pooledObject = pooledObject;
}
public void callPooledObjectMethod()
{
pooledObject.foo();
}
}
@Scope(value = "prototype", proxyMode = ScopedProxyMode.INTERFACES)