在 Spring 或者其他依赖注入框架中,不同的注入方式各有优缺点。本文对 @Autowired
、@Resource
、构造器注入,以及 @RequiredArgsConstructor
(Lombok 提供的简化构造器注入的注解)进行详细对比,并给出最佳实践。
1. @Autowired
注入
用法:
@Component
public class MyService {
@Autowired
private DependencyService dependencyService;
}
优缺点:
✅ 优点:
方便,直接标注在字段上,Spring 自动注入。
可以用于字段、构造器和 setter 方法,使用灵活。
❌ 缺点:
字段注入(Field Injection)不推荐,因为:
不利于单元测试(无法直接在测试中构造实例并注入依赖)。
隐藏依赖关系,类的依赖项不明显,影响可读性。
不便于构造函数初始化,无法强制依赖项的存在。
2. @Resource
注入
用法:
@Component
public class MyService {
@Resource
private DependencyService dependencyService;
}
优缺点:
✅ 优点:
@Resource
是 JSR-250 规范的一部分,兼容 Spring 和 Java EE,支持name
指定具体 Bean。比
@Autowired
更直观,避免@Autowired
的 required 属性问题(@Resource
默认必须存在 Bean)。
❌ 缺点:
也是字段注入,同样不利于测试和依赖管理。
失去了 Spring 强大的
@Primary
和@Qualifier
机制。
3. 构造器注入(Constructor Injection)【推荐 ✅】
用法:
@Component
public class MyService {
private final DependencyService dependencyService;
@Autowired // Spring 4.3+ 可省略
public MyService(DependencyService dependencyService) {
this.dependencyService = dependencyService;
}
}
优缺点:
✅ 优点:
强制依赖注入,如果某个依赖缺失,代码无法编译,避免 NPE。
有利于单元测试,可以直接用
new MyService(mockDependencyService)
创建实例。依赖关系清晰,构造方法明确表明这个类需要哪些依赖。
❌ 缺点:
当依赖项过多时,构造函数可能变得很长(通常这是代码设计的问题,可以考虑拆分)。
4. @RequiredArgsConstructor
(Lombok)注入【推荐 ✅】
用法:
@RequiredArgsConstructor
@Component
public class MyService {
private final DependencyService dependencyService;
}
优缺点:
✅ 优点:
本质上是构造器注入的简化形式,自动为
final
字段生成构造方法。避免冗长的构造方法声明,提高可读性。
❌ 缺点:
依赖 Lombok,如果团队不使用 Lombok 可能会有额外学习成本。
不能自定义构造方法(除非搭配
@AllArgsConstructor
)。
推荐的最佳实践
优先使用构造器注入(Constructor Injection)
依赖项明确,避免 NPE,方便测试。
Spring 4.3+ 不需要
@Autowired
,自动注入构造函数参数。
Lombok 的
@RequiredArgsConstructor
可以简化构造器注入适用于
final
依赖项,减少样板代码。
不推荐字段注入(
@Autowired
、@Resource
)不利于测试,隐藏依赖关系。
只有在特殊情况下才用(如 AOP 代理、Spring 内部管理 Bean)。
Setter 注入适用于可选依赖
@Component public class MyService { private DependencyService dependencyService; @Autowired public void setDependencyService(DependencyService dependencyService) { this.dependencyService = dependencyService; } }
但通常应当避免,除非有明确需求(例如可以延迟注入)。
最终结论
如果你的项目支持 Lombok,推荐 @RequiredArgsConstructor
,否则推荐手写构造器注入。