首页 > 其他分享 >深入探索Spring注入:解锁@Autowired与构造器注入的秘密

深入探索Spring注入:解锁@Autowired与构造器注入的秘密

时间:2024-03-12 15:45:01浏览次数:23  
标签:依赖 Autowired Spring bean 注入 构造函数

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

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

标签:依赖,Autowired,Spring,bean,注入,构造函数
From: https://www.cnblogs.com/brianinzz/p/18068466

相关文章

  • Spring 知识点
    SpringSpring是什么?Spring为了解决企业级应用的复杂性而创建,简化开发。如下简化:基于POJO的轻量级和最小侵入性编程;以IoC(控制反转)、DI(依赖注入)和面向接口实现松耦合;基于AOP(切面编程)和惯性进行声明式编程;以切面和模版减少样式代码;SpringIoC(控制反转)IoC负责创建、......
  • springboot-yaml语法
    SpringBoot使用一个全局的配置文件,配置文件名称是固定的application.properties语法结构:key=valueserver.port=8080application.yml语法结构:key:空格value普通的key-valueserver:port:8080yaml后缀配置可以存储对象,而properties只能保存键值对yaml不仅可以用来......
  • Spring中使用自带@Autowired注解实现策略模式
    场景SpringBoot中策略模式+工厂模式业务实例(接口传参-枚举类查询策略映射关系-执行不同策略)规避大量if-else:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/130503707设计模式-策略模式在Java中的使用示例:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/d......
  • 最新宽字节注入攻击和代码分析技术
    宽字节注入攻击宽字节注入攻击的测试地址在本书第2章。访问id=1',页面的返回结果如图4-51所示,程序并没有报错,反而多了一个转义符(反斜杠)。   图4-51  从返回的结果可以看出,参数id=1在数据库查询时是被单引号包围的。当传入id=1'时,传入的单引号又被转义符(反斜杠)转义,导......
  • 【2024面试刷题】二、Spring Cloud 面试题之Hystrix
    1、springcloud断路器的作用是什么?答:当一个服务调用另一个服务由于网络原因或自身原因出现问题时,调用者将等待被调用者的响应当更多的服务要求这些资源导致更多的请求等待时,就会出现连锁效应(雪崩效应)。断路器完全打开:一段时间内达到一定次数不能调用并且多次监测无恢复迹象......
  • SpringBoot自定义validation注解校验参数只能为指定的值
    需求:实体类中某个属性的值必须为指定的值,比如0或者1SpringBoot版本:2.4.8validation 依赖<!--数据校验--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>......
  • Spring状态机(FSM),让订单状态流转如丝般顺滑
    引言在复杂的应用程序设计中,尤其是那些涉及多个状态变迁和业务流程控制的场景,有限状态机(FiniteStateMachine,FSM)是一种强大而有效的建模工具。Spring框架为此提供了Spring状态机(SpringStateMachine)这一组件,它允许开发者以一种声明式且结构清晰的方式来管理和控制对象的状态......
  • springBoot
    **Springboot**的主要优点:为所有spring开发者更快的入门开箱即用,提供各种默认配置来简化项目配置内嵌式容器简化web项目没有冗余代码生成和xml配置的要求MVCMVVM微服务架构微服务是一种架构可以把原先是一个整体的模块进行拆分成小模块去进行操作,其不会对其整体模块进行......
  • k01创建第一个springboot程序
    创建springboot程序的方式有两种1、在spring官网创建,https://start.spring.io/2、使用idea程序创建。一般情况下我们都是使用idea软件创建的,因为这样会更方便1、使用spring官网创建(SpringInitializr)(初学使用)(一般不用)我们只需要在网站上输入(https://start.spring.i......
  • Spring多线程事务处理
    一、背景本文主要介绍了spring多线程事务的解决方案,心急的小伙伴可以跳过上面的理论介绍分析部分直接看最终解决方案。在我们日常的业务活动中,经常会出现大规模的修改插入操作,比如在3.0的活动赛事创建,涉及到十几张表的插入(一张表可能插入一行或者多行数据),由于单线程模型的关系,......