Spring原型bean与单例bean和dependency injection相结合。 是否只有配置方法?

我有一个单例bean,它需要每次调用一个函数来返回对不同(新)原型bean的引用。 我能想到的唯一方法是通过调用其getBean()方法以编程方式从BeanFactory / ApplicatioContext中检索新的原型bean实例。 代码示例将遵循……

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

  public class ProtoBean { .... } public class SingletonBean { private BeanFactory factory; public ProtoBean dispense() { return (ProtoBean) factory.getBean("protoBean"); } .... } 

看一下Method Injection

从Spring 3.0开始,我们可以使用来dependency injection适当的范围。 在场景背后,Spring注入代理对象并负责查找正确的范围上下文,可能是原型,会话或请求等。请参阅此处的官方文档。

为了简化生活,Spring还为@Scope引入了proxyMode属性,因此我们不仅限于XML声明。 例如:

 @Scope(value = "prototype", proxyMode = ScopedProxyMode.INTERFACES) 

确保明确记录注入的bean是一个代理,以警告其他人getClass()和cast可能不会产生预期的结果。 此外,请确保代理类中的equals()和hashCode()使用访问方法,而不是直接访问类变量。

使用方法注入会使singleton-bean类难以进行unit testing(您需要创建一个子类来实现赋予依赖性的方法)。 另外它不太可重用,因为你不能直接实例化它,所以如果你不使用Spring并想要使用这个类,你需要子类并提供bean返回方法。

一个更好的方法IMHO是使用代理,原型目标源和原型目标bean,如下所示。 这种单例bean类很容易进行unit testing,可以更好地重复使用。

             

现在我们可以将pooledObject注入一个单独的bean( poolConsumer如上所示),以及我们在该单例bean上进行的每个方法调用,(例如,每次调用poolConsumer.callPooledObjectMethod() ,然后调用pooledObject.foo() )我们得到一个新的PooledObject bean。

以下是相应的代码:

 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(); } }