彻底学会@Autowired和@Resource

看完你能学会

  • @Resource和@Autowired区别
  • IDEA使用@Autowired为什么有警告,
  • spring推荐使用那种方式进行注入

1. @Autowired作用

  • 来源: Spring 框架自带的注解。
  • 注入方式: 默认按类型(byType)注入。
  • 使用场景: 通常用于注入 Spring 管理的 Bean。
  • 特点:
    • 默认按类型匹配,如果找到多个相同类型的Bean,会按名称匹配。
    • 可以与 @Qualifier 注解结合使用,指定具体的 Bean 名称。
    • 支持 required 属性,默认为 true,表示必须注入,如果找不到 Bean 会抛出异常。设置为 false 时,允许注入为 null

2. @Resource作用

  • 来源: JSR-250 标准注解,属于 Java EE 规范,Spring 也支持。
  • 注入方式: 默认按名称(byName)注入。
  • 使用场景: 适用于需要按名称注入 Bean 的场景。
  • 特点:
    • 默认按名称匹配,如果找不到指定名称的Bean,会回退到按类型匹配。
    • 可以通过 name 属性指定 Bean 的名称。
    • 不支持 required 属性,如果找不到 Bean 会抛出异常。

3. 为什么IDEA使用@Autowried会有警告

  • 首先这个警告只会在字段注入的时候提示
查看代码测试
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//提示警告⚠️
public class OperationController {
@Autowired
private CmdbProvider cmdbProvider;
。。。。
}

//这样就不会有警告(set之所以没有警告,是因为这样有其他应用场景,下面有解释)
public class OperationController {
private CmdbProvider cmdbProvider;

@Autowired
public void setCmdbProvider(CmdbProvider cmdbProvider) {
this.cmdbProvider = cmdbProvider;
}
。。。。
}
  • 因为@Autowired是spring提供的注解,而spring其实并不推荐这种注入方式,所以IDEA在检测代码规范时,如果是@Autowired就会使用spring的最佳实践来检查,所以才会有警告

4. @Resource为什么没有警告

  • 因为@Resource是java官方提供的注解,所以IDEA在检查@Resource时会使用java的标准去检查,所以没有警告

5.最后

其实对于spring来说,他们既不推荐使用@Autowired,也不推荐使用@Resource进行字段的注入,而是更推荐使用构造方法 进行注入

  • 构造注入的优点
  1. 依赖关系清晰 ,可以在构造方法中看到所有依赖的其他类
  2. 方便测试 可以直接在调用构造方法时传入自己new出来的对象,如果是字段注入,需要启动整个spring容器才能进行代码的测试
  3. 构造注入可以将字段用final修饰,可以作为一个常量,不会被恶意修改,更安全

  4. 符合单一职责原则 ,如果一个类中构造器参数过多,可能意味着这个类的职责过重,需要拆分
  5. 避免循环依赖 ,如果存在循环依赖,项目启动会抛出异常(BeanCurrentlyInCreationException)
  6. spring官方推荐注入方法:构造注入 > set注入(适合可选依赖或需要动态配置的场景) > 字段注入(不推荐)

查看代码测试
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

#⚠️简化版本要求spring版本大于4.24.3之后的版本spring增加了新特性,就是当一个类只有一个构造函数时,会自动注入
#⚠️否则需要显示声明@Autowired注解才会注入
#下面有spring和springboot版本对应关系

#✅构造注入的简化版本
@Component
#lombok自动生成构造方法
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
}

#构造注入
@Component
public class UserService {
private final UserRepository userRepository;

// 推荐的做法,构造方法注入
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}

字段注入
@Component
public class UserService {
@Autowired
private UserRepository userRepository;

public void doSomething() {
userRepository.save(new User());
}
}


Spring Boot 版本 Spring Framework 版本
1.0.x 4.0.x
1.1.x 4.0.x
1.2.x 4.1.x
1.3.x 4.2.x
1.4.x 4.3.x
1.5.x 4.3.x
2.X 5.X
3.x 6.x