Java Spring原型bean与单例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的引用。我能想到的唯一方法是通过调用其getBean()方法,以编程方式从BeanFactory/ApplicationContext检索一个新的原型bean实例。下面是代码示例

有更好的方法吗?希望只能通过配置?(就我个人而言,我怀疑有…)


公共类原型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)