构造器注入是spring官方首推方式,通过构造方法传入依赖项并设为final,确保对象不可变、依赖不为空、线程安全且易于测试。

依赖注入通过构造方法实现,就是把对象所依赖的其他对象(即“依赖项”)作为参数,在创建该对象时通过构造函数传入,而不是在类内部用 new 主动创建。这种方式让类更松耦合、更易测试、更符合单一职责和控制反转原则。
构造方法注入的基本写法
被注入的类(比如 UserService)定义一个带参数的构造方法,参数类型是它所依赖的接口或具体类(比如 UserRepository)。外部容器(如 Spring)或手动代码在实例化时传入已准备好的依赖实例。
- 依赖通常声明为
final字段,确保不可变性和初始化安全 - 构造方法中直接赋值给成员变量,不执行复杂逻辑
- 避免在构造方法里调用可能抛异常或依赖未就绪的方法
Spring 中的典型用法
Spring 5.0+ 默认支持无注解的构造注入:只要类只有一个构造方法,Spring 就会自动使用它;有多个构造方法时,加 @Autowired 明确指定(Spring 4.3+ 可省略该注解,前提是只有一个构造方法)。
例如:
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
只要 UserRepository 在 Spring 容器中有对应 Bean(比如标记了 @Repository),启动时就会自动注入。
手动构造注入(非框架场景)
没有 Spring 时,也可以手动实现依赖注入,体现设计思想:
- 先创建依赖对象:如
UserRepository repo = new JdbcUserRepository(); - 再用它构造目标对象:
UserService service = new UserService(repo); - 后续所有业务操作都基于这个已注入依赖的
service实例
这样,UserService 不关心 UserRepository 怎么创建、用什么数据库,只专注自身逻辑。
为什么推荐构造注入而非 setter 或字段注入
构造注入能保证依赖不为空,类一创建就处于可用状态:
- 字段注入(
@Autowired private Xxx xxx;)无法设final,且测试时需反射或额外工具模拟 - setter 注入允许对象创建后才设依赖,容易遗漏,状态不稳定
- 构造注入天然支持不可变性、线程安全,也便于单元测试(直接 new 并传入 mock 对象)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










