金三银四面试:@Autowired与构造器注入区别

好久没有写JAVA了 今天突然看到Sonarlint的提示

什么??竟然不推荐这样写? 难道我一直写的都是错的?? 所以我深入了解了一下为什么要我改成构造函数注入

在Spring框架中,依赖注入(DI)是一种核心功能,它允许对象通过构造函数、setter方法或字段直接定义其依赖关系。这里,我们专注于两种常见的注入方式:字段注入(通过@Autowired注解)和构造函数注入。理解这两种注入方式的全过程对于编写可维护、可测试和健壮的Spring应用至关重要。

字段注入(使用@Autowired)

字段注入是Spring允许的依赖注入的简便方式,它直接在类的字段上使用@Autowired注解。这种方式的注入流程相对简单直接:

注入全过程

  1. 启动阶段:当Spring应用启动时,Spring容器开始创建并管理bean。它扫描项目中的类,查找带有@Component、@Service、@Controller等注解的类,并为这些类创建bean。
  2. 依赖查找:在字段上使用@Autowired时,Spring容器在运行时自动检测系统中可用的匹配该字段类型的bean。
  3. 自动注入:容器将找到的bean直接注入到被@Autowired标记的字段中。这一过程通常在bean的构造函数执行之后发生,意味着新创建的对象的字段将在稍后的时间点被Spring自动填充。
  4. 后处理:一旦所有的字段被注入后,bean才被认为是完全初始化的,并且随后会触发任何回调方法,如标记有@PostConstruct的方法。

优点与缺点

优点

  • 简单易用:直接在字段上标注@Autowired,无需额外的构造函数或setter方法。
  • 代码简洁:减少了模板代码,特别是在依赖数量不多时。

缺点

  • 不支持不可变性:由于字段是在对象创建后注入,不能声明为final。
  • 降低可测试性:不使用Spring容器时,例如在单元测试中,很难替换依赖项。
  • 违反了Spring推荐的最佳实践:构造函数注入是推荐的方式,因为它支持不可变性,并且依赖在使用前总是被初始化。

构造函数注入

构造函数注入是将依赖作为参数传递给类的构造函数。Spring容器使用这些参数来创建bean实例。

注入全过程

  1. 启动阶段:与字段注入相同,Spring首先创建所有的bean定义,并扫描标注了Spring注解的类。
  2. 依赖解析:对于构造函数注入,当创建类的实例时,Spring容器查看类的构造函数参数,确定需要注入哪些依赖。
  3. 依赖注入:Spring容器然后实例化这些依赖(如果它们尚未创建)并通过构造函数注入到正在创建的bean中。这确保了在对象完全构造之前所有必需的依赖都已经提供。
  4. 对象初始化:一旦所有构造函数参数被注入,对象被实例化,并且所有设置方法和回调都被调用。

优点与缺点

优点

  • 支持不可变性:依赖可以被声明为final,确保了一旦构造对象后不会改变。
  • 促进了更好的软件设计:构造函数注入强制要求依赖在构造对象时必须存在,从而保证了bean的依赖不会是null。
  • 提高可测试性:容易在测试中通过构造函数替换依赖,特别是使用Mock对象时。

缺点

  • 构造函数臃肿:如果一个类有多个依赖,构造函数可能会变得很长,这可能使代码更难阅读和维护。
  • 可能需要更多配置:特别是在存在多个构造函数或需要特定的配置来选择适当构造函数时。

对比总结

字段注入和构造函数注入在Spring中都是实现依赖注入的有效方式。然而,构造函数注入通常被视为更好的实践,因为它支持不可变性、有助于确保依赖的及时提供,同时还增强了代码的可测试性。字段注入虽然代码更简洁,但它在测试性和代码清晰度方面表现较差。

在选择适合项目的注入方式时,重要的是考虑到具体的应用场景、团队的编码标准以及维护和测试的便利性。理解各自的注入流程和特点可以帮助开发者做出最适合他们需要的选择。

相关推荐
数据狐(Datafox)几秒前
京东商品列表API技术解析与落地应用(含标准 JSON 示例)
java·大数据·前端·人工智能·python·数据分析·json
摇滚侠10 分钟前
《SpringBoot 3:入门与应用实战》第 7 章 AOP 思想与实现 阅读笔记 15
java·spring boot·笔记
风尘小子27 分钟前
java静态类使用@Value动态绑定环境变量
java
重生之后端学习43 分钟前
239. 滑动窗口最大值[困难]✅
java·数据结构·算法·leetcode·职场和发展
脉动数据行情11 小时前
Java SpringBoot 对接知名台股 TWSE|批量采集上市股票行情实践
java·开发语言·spring boot
她的男孩1 小时前
我把管理系统接给AI,它改条数据都要先问我
java·后端·架构
toolsmith1 小时前
我用AI拆解了Charles的授权机制,发现密钥被写死在了代码里
java·人工智能
IKUN家族2 小时前
SpringBoot日志
java·开发语言
DianSan_ERP2 小时前
WMS接入电商平台自动化履约实战:一张订单从平台到出库的接口时序设计
java·前端·网络·数据库·安全·架构·自动化
liangsheng_g2 小时前
微服务本地开发零配置隔离方案
java·微服务·架构