在 spring 框架中创建有状态对象的一种方法

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 = https://www.it610.com/article/data; }public void newRecord() { store.store(this.data); } } }

【在 spring 框架中创建有状态对象的一种方法】Model 类是我们要创建的有状态对象,它是 ModelFactory 的内部类。我们在 ModelFactory 注入 Model 需要使用的 Spring Bean Store,这样 Model 在执行 newRecord 时就可以直接调用 Store 的方法了。因为不能直接创建 Model 所以提供一个 createModel 方法用于创建 Model 对象。我们在创建 Model 对象时调用方只需要关心 Model 相关的属性,同时不需要关心其它依赖,完美的解决了前文两种方法的弊端。

    推荐阅读