8.依赖注入的几种方式
8.1.字段注入
字段注入(@Autowired 写在属性上,最常见,但不推荐生产!!!)
java
@Service
public class UserController {
@Autowired
private UserService userService;
}✅ 优点:写法简短、代码少
❌ 缺点:
- 无法标记
final - 不能在构造前做校验,单元测试不方便
- 属于 Spring 专属注解,耦合 Spring
特别提示
Spring 官方已经不推荐优先使用字段注入,不推荐在生产中使用!!!
8.2.构造器注入(Spring 官方首选推荐)
原理:Spring 调用类的构造方法,把 Bean 传进来赋值。
✅优点:支持 final、依赖强制校验、单元测试友好、不可变
8.2.1.手写构造
手写构造(只有一个构造,不用 @Autowired)
java
@Service
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
}8.2.2.Lombok 简化写法()
只对加了 final 的字段生成构造方法,底层依然是构造注入!需要配合@RequiredArgsConstructor使用,代码示例如下:
java
@Service
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
private final DeptService deptService;
}重点!!!
@RequiredArgsConstructor+final推荐企业级开发使用。
在需要注入的属性前面必须加final,否则不会注入!!!
如果有多个接口类实现出现了冲突的解决方案如下:
java
@Service
@RequiredArgsConstructor
public class UserController {
@Qualifier("userServiceImpl1-这里写你不同实现类的类名")
private final UserService userService;
private final DeptService deptService;
}使用提示
RequiredArgsConstructor和另外两个 lombok 构造注解区分(很容易混)
- @RequiredArgsConstructor:只给
final/@NonNull的字段生成构造器(我们注入 Bean 首选) - @AllArgsConstructor:给所有字段生成全参构造
- @NoArgsConstructor:生成无参构造(Mybatis、序列化经常要用)
8.3.Setter方法注入
@Autowired 打在 set 方法上,Spring 创建完对象之后再调用 set 赋值。
✅ 优点:可以可选注入(如果 Bean 不存在不强制报错)、方便重新设置依赖
❌ 缺点:代码多;对象创建后还能修改依赖
👉 适用:依赖可选、不是必须的依赖
java
@Service
public class UserController {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
}