为什么Spring和IDEA不推荐使用@Autowired和@Resource注入Bean
@Autowired和@Resouce的区别
1.@Autowired是Spring官方提供的注解,而@Resource注解是J2EE本身提供的
2.@Autowired是通过类型进行注入,而@Resource是通过名称进行注入
3.@Autowired的使用,必须要该对象存在于IoC容器中
4.@Autowired可以对构造器、方法、参数、字段使用,@Resource只能对方法、字段使用
既然@Autowired是Spring官方提供的,为什么又不推荐了呢?
@Autowired
首先我们经常遇到的,就是在IDEA使用@Autowired注解的时候,经常出现波浪下划线的情况。这种下划线的出现通常表示为过时的或者是不推荐使用的。那么为什么不推荐使用呢?
实际上这种注入方式存在很多的问题:
1. 不可见的依赖关系
字段注入将依赖关系隐藏在类的内部,使得类的依赖关系不明显。这会导致以下问题:
- 代码可读性差:其他开发者在阅读代码时,很难一眼看出该类依赖于哪些其他类。
- 代码可维护性差:在进行代码重构或维护时,开发者需要花费更多时间去理解和修改这些隐藏的依赖关系。
2. 无法使用final修饰符
由于字段注入是在对象实例化之后进行的,字段不能用final修饰。这会导致以下问题:
- 不变性(immutability)问题:无法确保依赖关系在对象生命周期内保持不变,从而可能引发难以调试的bug。
- 设计上的局限:无法利用Java语言的特性来设计出更稳固和安全的代码结构。
3. 测试不便
字段注入使得单元测试变得困难。使用字段注入时,测试类需要借助反射机制来注入依赖,这不仅繁琐,还容易出错:
@SpringBootTest
class BeanInjectApplicationTests {
@Nested
class MyServiceTest {
@InjectMocks
private MyService myService;
@Mock
private MyRepository myRepository;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testServiceMethod() { // test implementation }}
}
}
}
4. 依赖注入框架的绑定
字段注入强依赖于依赖注入框架(如Spring)。一旦脱离了框架的管理,类将无法正常工作,限制了代码的可移植性和可复用性。
@Resource
为什么@Resource没有波浪下划线: @Resource相对@Autowired对IoC容器的耦合更低
那么我们在进行依赖注入时,到底用什么方式?
Spring官方推荐:构造器注入
优点:
- 清晰的依赖关系:所有依赖关系在类实例化时就明确了,代码可读性和可维护性大大提高。
在我们的注入存在循环依赖时,可以直接对我们进行清晰的提示:
- 不变性:可以使用final修饰符,确保依赖关系在对象生命周期内保持不变。
在这里有一个特别有意思的事情,这个文档的SpringBoot版本为2.7.18,虽然代码已经写的是采用构造器注入的方式,但是上方的说明依旧是推荐使用@Autowired进行注入,我想这也是开源社区文档维护的问题吧。