将原型与单例混合
Posted
技术标签:
【中文标题】将原型与单例混合【英文标题】:Mixing prototypes with singletons 【发布时间】:2015-06-05 21:32:29 【问题描述】:我在 Spring 中有一些应用程序,它会根据每个请求创建原型 bean X(来自工厂)。这个 bean X 有一些 DAO 单例,例如我工作的 Y、Z 和 SomeObject(设置值等)
@Scope(value="prototype")
public class X
@Autowired
private Y y;
@Autowired
private Z z;
private SomeObject obj;
public void someMethod()
obj.setProperty();
这是正确的方法吗?我的意思是,在每个请求中,Spring容器必须搜索那些单例bean并将它们注入原型,它有效吗?或者最好是创建无状态 bean 并以适当的方法创建 SomeObject 实例,然后在我想使用它时将它传递给函数参数(这不太舒服)?
【问题讨论】:
我假设someMethod()
将有效地使用y
和z
? (你能更正代码吗:X
应该是类中的Y
)。
是的,someMethod() 有效地使用 y 和 z 为 obj 生成一些数据。已更正。
但SomeObject
只是X
的内部状态,它在对X
的不同方法的各种调用之间保持某种状态,还是从X
外部可见?
是的,从外面可以看到。 X 是具有状态的原型 bean。
【参考方案1】:
最好使用单例范围和无状态 bean,因为无状态 bean 是线程安全的。仅当您不能使用无状态时才使用有状态 bean。
【讨论】:
是的,我知道,但是在“清洁代码”系列的每一本书中都提到尽可能使用实例变量,因为它使代码更具可读性,并且不需要传入对象每个方法都需要更改(例如,如果我们有 10 个方法怎么办?在每个方法中,方法定义中都必须有 SomeObject 变量)。它让 sping bean 读起来真的很糟糕,但肯定是线程安全的, 所有规则都有一个范围 =) 实例变量对于具有复杂逻辑的类来说是一个很好的解决方案。但是服务(或其他构建块,如数据访问对象)应该是无状态的。您可以结合这些规则并在非spring helper 类中使用实例变量,然后在单例服务中创建该类的局部变量实例。以上是关于将原型与单例混合的主要内容,如果未能解决你的问题,请参考以下文章
JS面向对象基础讲解(工厂模式构造函数模式原型模式混合模式动态原型模式)