在Spring开发领域中,尤其是在Spring Boot框架中,@Autowired
注解一直是将依赖项注入Spring管理的Bean的常用手段。然而,随着Spring最佳实践的发展和新功能的引入,@Autowired
已不再是推荐的依赖注入方式。对于熟悉旧版Spring的开发人员而言,这种转变可能会让熟悉旧版本的开发人员感到意外。本文将探讨为什么@Autowired
正在失去其原有的地位,Spring推荐的替代方案有哪些,以及如何现代化Spring代码库。
什么是 @Autowired
?
在我们讨论Spring不再推荐@Autowired
之前,先快速了解一下@Autowired
的作用。@Autowired
用于将依赖注入到类中,这可以应用于字段(field)、构造函数和setter方法,Spring在应用程序启动时自动注入所需的bean。
比如说:
/**
* 这是一个服务类,名为MyService,它依赖于MyRepository。
*/
@Service
public class MyService {
@Autowired
private MyRepository myRepository;
}
在这个情况下,Spring 在创建 MyService
实例时,注入了一个 MyRepository
实例。
尽管这种方法效果不错,但也有其不足之处,特别是在更大、更复杂的应用程序中。让我们来看看原因。
@Autowired
的毛病
- 隐藏的依赖:当在字段上使用
@Autowired
时,依赖会在幕后注入,这可能导致隐藏的依赖。这种做法使得很难明确一个类正常工作所需要的依赖,从而增加了测试和调试的复杂性。 - 不可变性问题:字段注入允许依赖是可变的,使得类可以稍后更改它们。这降低了组件的不可变性,从而导致难以追踪的错误。
- 测试困难:依赖关系通过字段注入的组件在测试时可能比较棘手。由于依赖关系没有通过构造函数传递,你需要在测试设置中手动模拟或注入这些字段,这会增加不必要的样板代码。
- 基于构造函数的注入更清晰:通过构造函数的注入,依赖关系在构造函数中显式声明,使得所需的组件一目了然。这种方法使类更易读,更容易测试,同时提升了整体的可维护性。
近年来,Spring团队倾向于将构造器注入作为处理依赖注入的首选方式,而不再使用@Autowired
进行字段注入。这里有一些原因:
- 构造器注入使依赖关系更加明确,有助于实现无副作用。
- 它有助于确保对象在创建时就具有所有必要的依赖关系,从而避免部分初始化的问题。
- 使得单元测试更容易,因为所有依赖项都是通过构造函数传递的。
1. 必要的依赖项:构造函数注入强制你在创建类的实例时提供所有必需的依赖。这确保该类在创建时总是处于有效且完整的状态,所有必要的依赖项都已设置。
@Service
public class MyService {
// 定义一个私有且不可变的MyRepository对象
private final MyRepository myRepository;
// 构造函数,通过注入的方式初始化myRepository对象
public MyService(MyRepository myRepository) {
this.myRepository = myRepository;
}
}
在此示例中,Spring 会自动将 MyRepository
注入构造器中,确保 MyService
始终用有效的仓库对象初始化。
2.不可变:构造器注入鼓励使用 final
字段,从而使得对象变得不可变。一旦注入依赖项,它们将不能被改变,从而减少了意外修改和代码错误的可能性。
3.增强的可测试性:使用构造器注入进行组件测试要容易得多。在测试时,你只需将模拟依赖直接传递给构造器,而无需依赖Spring的内部配置。
4.无需@Autowired
: 如果一个类只有一个构造方法,Spring 可以自动注入其依赖,从而无需使用 @Autowired
注解。这简化了代码,减少了注解的冗余。
@RequiredArgsConstructor
火了
对于那些使用构造器注入的类来说,另一个有用的工具是 Lombok 的 @RequiredArgsConstructor
注解。此注解会自动生成一个包含必填字段(这些字段标记为 final)的构造器,从而进一步减少了样板代码。
@Service
@RequiredArgsConstructor
public class MyService {
private final MyRepository myRepository;
}
使用 @RequiredArgsConstructor
,可以自动注入必要的依赖项,而无需手动编写构造函数,从而使代码保持干净和简洁。
@Autowired
(自动注入)依然很有用,但请谨慎使用
重要的是要注意,Spring 没有弃用 @Autowired
,并且完全不推荐使用这个说法也不准确。在某些情况下它仍然有用,例如:
- setter 注入方式:在某些情况下,当你希望使用 setter 注入时,可以这样做,如果依赖是可选的,或者你可以在对象创建后注入值。然而,尽量少用 setter 注入,仅在必要时才使用。
@Service
public class MyService {
// 该类用于管理MyRepository的注入
private MyRepository myRepository;
@Autowired
public void setMyRepository(MyRepository myRepository) {
this.myRepository = myRepository;
}
}
- 遗留代码:如果你正在处理遗留代码库,你可能会遇到
@Autowired
注解。你不需要立即重构所有@Autowired
的实例,但在你更新和重构代码的过程中,可以考虑逐步过渡到构造器注入。
总结:告别 @Autowired
,继续前行
在现代 Spring 开发中,一般来说,构造器注入被认为是依赖注入的最佳实践,提供更干净、更易于维护和测试的代码。虽然 @Autowired
仍然可用,但理解其局限以及 Spring 为何建议不再使用它非常重要。
以下是一些关键要点:
- 构造器注入有助于提高代码的不可变性和清晰度。
- 使用构造器注入会使测试变得更加容易,因为你可以直接注入模拟对象或存根。
- Lombok 的
@RequiredArgsConstructor
可以简化基于构造器的依赖注入。 - 尽量少用
@Autowired
,仅在其他注入方法不适用时才使用。
通过采用这些做法,你可以编写更简洁、更健壮的Spring应用程序,这样的应用程序随着时间更易于维护和测试。
共同学习,写下你的评论
评论加载中...
作者其他优质文章