将原型与单例混合

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() 将有效地使用yz? (你能更正代码吗:X 应该是类中的Y)。 是的,someMethod() 有效地使用 y 和 z 为 obj 生成一些数据。已更正。 SomeObject 只是X 的内部状态,它在对X 的不同方法的各种调用之间保持某种状态,还是从X 外部可见? 是的,从外面可以看到。 X 是具有状态的原型 bean。 【参考方案1】:

最好使用单例范围和无状态 bean,因为无状态 bean 是线程安全的。仅当您不能使用无状态时才使用有状态 bean。

【讨论】:

是的,我知道,但是在“清洁代码”系列的每一本书中都提到尽可能使用实例变量,因为它使代码更具可读性,并且不需要传入对象每个方法都需要更改(例如,如果我们有 10 个方法怎么办?在每个方法中,方法定义中都必须有 SomeObject 变量)。它让 sping bean 读起来真的很糟糕,但肯定是线程安全的, 所有规则都有一个范围 =) 实例变量对于具有复杂逻辑的类来说是一个很好的解决方案。但是服务(或其他构建块,如数据访问对象)应该是无状态的。您可以结合这些规则并在非spring helper 类中使用实例变量,然后在单例服务中创建该类的局部变量实例。

以上是关于将原型与单例混合的主要内容,如果未能解决你的问题,请参考以下文章

JS面向对象基础讲解(工厂模式构造函数模式原型模式混合模式动态原型模式)

静态代码块和单例混合

厘清面向对象四种模式:工厂模式构造函数模式原型模式混合模式

构造函数+原型的js混合模式

JavaScript继承基础讲解,原型链借用构造函数混合模式原型式继承寄生式继承寄生组合式继承

关于js的设计模式(简单工厂模式,构造函数模式,原型模式,混合模式,动态模式)