Skip to content

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 构造注解区分(很容易混)

  1. @RequiredArgsConstructor:只给 final / @NonNull 的字段生成构造器(我们注入 Bean 首选)
  2. @AllArgsConstructor:给所有字段生成全参构造
  3. @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;
    }
}