为什么Spring和IDEA不推荐使用@Autowired和@Resource注入Bean

257 阅读3分钟

为什么Spring和IDEA不推荐使用@Autowired和@Resource注入Bean

@Autowired和@Resouce的区别

1.@Autowired是Spring官方提供的注解,而@Resource注解是J2EE本身提供的

2.@Autowired是通过类型进行注入,而@Resource是通过名称进行注入

3.@Autowired的使用,必须要该对象存在于IoC容器中

4.@Autowired可以对构造器、方法、参数、字段使用,@Resource只能对方法、字段使用

既然@Autowired是Spring官方提供的,为什么又不推荐了呢?

@Autowired

image-20240802144332899.png

首先我们经常遇到的,就是在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官方推荐:构造器注入

image-20240802145301839.png

优点:

  • 清晰的依赖关系:所有依赖关系在类实例化时就明确了,代码可读性和可维护性大大提高。

在我们的注入存在循环依赖时,可以直接对我们进行清晰的提示:

image-20240802145301839

  • 不变性:可以使用final修饰符,确保依赖关系在对象生命周期内保持不变。

在这里有一个特别有意思的事情,这个文档的SpringBoot版本为2.7.18,虽然代码已经写的是采用构造器注入的方式,但是上方的说明依旧是推荐使用@Autowired进行注入,我想这也是开源社区文档维护的问题吧。