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
@Component
public 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 相干的属性,同时不须要关怀其它依赖,完满的解决了前文两种办法的弊病。