Spring 框架作为 Java 社区的支流框架,绝大部分 Java 我的项目都会应用。然而 Spring 框架其实诞生的很早,在诞生之初次要是为了服务于过程式编程和传统面向对象编程,这些编程形式不须要应用有状态的对象,因而 Spring 的单例 Bean 非常适合。然而古代面向对象编程,强调了对属性的封装,因而都是有状态的对象,不再能把对象交给 Spring 治理。如果只是简略的对于属性的计算,间接 new 创立也不妨。然而不免有些办法须要产生一些副作用,要存数据库、抛事件等。这就须要在对象中依赖一些 Spring 的 Bean。
一种解决形式是,通过 set 办法或者构造函数引入 Spring 的 Bean。这种解决思路是很天然的抉择,然而这会让创建对象的中央感觉很惊讶,因为其难以了解这些依赖,也会让创建对象的形式很繁琐。
我也尝试过间接应用 Spring 提供的工具类间接在构造函数里获取 Bean。这样调用方就不再须要关怀对 Spring Bean 的依赖。然而这其实是一种反模式,违反了依赖注入的范式。
这两种办法各有优劣,是否有一种形式同时取得这两种办法的有点同时防止毛病呢。这个问题我摸索了很久,直到最近应用了一段时间的 Scala 社区的 ZIO 框架当前,找到了灵感。上面先贴出代码的实现。
package lano.whiteboard.application;import lombok.RequiredArgsConstructor;import org.springframework.stereotype.Component;@RequiredArgsConstructor@Componentpublic class ModelFactory { private final Store store; public Model createModel(String data) { return new Model(data); } public class Model { private final String data; public Model(String data) { this.data = data; } public void newRecord() { store.store(this.data); } }}
Model 类是咱们要创立的有状态对象,它是 ModelFactory 的外部类。咱们在 ModelFactory 注入 Model 须要应用的 Spring Bean Store,这样 Model 在执行 newRecord 时就能够间接调用 Store 的办法了。因为不能间接创立 Model 所以提供一个 createModel 办法用于创立 Model 对象。咱们在创立 Model 对象时调用方只须要关怀 Model 相干的属性,同时不须要关怀其它依赖,完满的解决了前文两种办法的弊病。