构造器注入是spring推荐的依赖注入方式,因其确保对象创建时依赖完整且不可变,提升可测试性与线程安全性;应声明final字段并在构造器中赋值,单构造器可省略@autowired,可选依赖用@nullable或optional处理。

在 Spring 中,构造器注入是推荐的依赖注入方式,它让对象在创建时就具备完整、不可变的依赖关系,提升可测试性和线程安全性。相比字段注入(@Autowired private XxxService service;),构造器注入更清晰、更安全。
为什么优先用构造器注入
字段注入隐藏了依赖,导致:
- 类无法脱离 Spring 容器独立实例化(影响单元测试)
- 依赖可能为 null(如未正确配置或循环依赖时)
- 违反“不可变性”原则——字段可被反射或后续代码修改
- IDE 和静态分析工具难以检测缺失依赖
如何正确定义构造器注入
将依赖声明为 final 字段,并在构造器中接收并赋值:
@Service
public class UserService {
private final UserRepository userRepository;
private final EmailService emailService;
// Spring 4.3+ 支持无 @Autowired 的单构造器自动注入
public UserService(UserRepository userRepository, EmailService emailService) {
this.userRepository = userRepository;
this.emailService = emailService;
}
public void createUser(User user) {
userRepository.save(user);
emailService.sendWelcomeEmail(user.getEmail());
}
}
注意:Spring 4.3 起,若类只有一个构造器,@Autowired 可省略;多个构造器时必须显式标注。
处理可选依赖或默认值
若某个依赖非必需,可用 @Nullable(Spring 5.0+)或 Optional<x></x> 声明:
public UserService(UserRepository userRepository,
@Nullable AuditService auditService) {
this.userRepository = userRepository;
this.auditService = auditService; // 允许为 null
}
// 或更推荐的方式:用 Optional 明确表达可选性
public UserService(UserRepository userRepository,
Optional<auditservice> auditService) {
this.userRepository = userRepository;
this.auditService = auditService.orElse(null);
}</auditservice>
与 Lombok 配合简化写法
使用 @RequiredArgsConstructor 自动生成含 final 字段的构造器(Spring Boot 2.1+ 默认支持):
@Service
@RequiredArgsConstructor
public class OrderService {
private final OrderRepository orderRepository;
private final final PaymentGateway paymentGateway;
// Lombok 自动生成:public OrderService(OrderRepository, PaymentGateway)
}
无需手写构造器,语义清晰,且保留不可变性与注入安全性。
不复杂但容易忽略:只要依赖不为空,就该走构造器注入;只有极少数场景(如依赖自身类型、延迟初始化)才考虑 @Lazy 或 setter 注入。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











