应使用构造器注入替代字段注入:将依赖声明为private final并移入构造函数,spring 5.0+可省略@autowired;确保所有强制依赖均通过构造器传入,提升可测性与不可变性,循环依赖时可用@lazy或重构解耦。

直接用构造器注入替代字段注入,核心就一条:把依赖从字段上挪到构造函数里,并声明为 final。
把@Autowired从字段移到构造器
字段注入写法(不推荐):
@Service<br>public class UserService {<br> @Autowired<br> private UserRepository userRepository;<br>}
改成构造器注入后:
@Service<br>public class UserService {<br> private final UserRepository userRepository;<br><br> public UserService(UserRepository userRepository) {<br> this.userRepository = userRepository;<br> }<br>}
Spring 5.0+ 中单构造器可省略 @Autowired 注解,容器会自动识别并注入。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
确保所有强制依赖都进构造器
一个类如果有多个依赖,全部列在构造器参数中:
- 每个依赖字段声明为 private final
- 构造器内完成赋值,不为空、不延迟初始化
- 避免出现部分字段靠 setter 或反射补全的情况
例如带配置参数的原型 Bean:
@Service @Scope("prototype")<br>public class Adapter {<br> private final AdapterService service;<br> private final Options options;<br><br> public Adapter(AdapterService service, Options options) {<br> this.service = service;<br> this.options = options;<br> }<br>}
测试时不再需要 Spring 上下文
字段注入的类无法直接 new 出来测试,而构造器注入让测试变得轻量:
- 单元测试中可自由传入 Mock 对象:
new UserService(mockRepo) - 无需
@InjectMocks、反射或ApplicationContext - 运行时也可通过
applicationContext.getBean(Bean.class, args...)动态传参
注意循环依赖场景
纯构造器注入遇到 A→B→A 会报错。若必须保留构造器注入又存在强耦合,可用:
-
@Lazy标注其中一个依赖参数,生成代理对象打破创建链 - 或改用字段注入(仅限该循环环节),其他依赖仍走构造器
- 更优解是重构职责,拆分逻辑降低耦合度










