Spring Boot中Bean的 构造器注入、字段注入和方法注入

在Spring中,依赖注入(DI)是实现控制反转(IoC)的一种方式,Spring提供了多种注入方式来将依赖关系注入到Bean中,常见的方式有构造器注入、字段注入和方法注入。下面将详细介绍这三种注入方式。

1. 构造器注入(Constructor Injection)

构造器注入是通过构造函数将依赖项注入到Spring Bean中。Spring容器会在创建Bean时,通过调用构造方法来注入依赖。

特点:
  • 适用于依赖是必需的情况。
  • 在Bean的构造函数中显式声明需要注入的依赖。
  • 一旦通过构造器注入后,Bean的依赖关系是不可变的(通常是final类型)。
使用方法:
  • 可以使用@Autowired注解标注构造器,Spring会自动选择构造器并注入需要的依赖。如果没有指定,Spring会注入符合构造函数参数的Bean。
@Component
public class MyService {

    private final MyRepository myRepository;

    @Autowired//可不写
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    public void performAction() {
        myRepository.saveData();
    }
}
  • 如果有多个构造器,Spring默认会注入标记有@Autowired注解的构造器。如果没有标注@Autowired,Spring会选择唯一一个构造函数来进行注入。
优点:
  • 强制依赖:确保依赖在Bean创建时就被注入,避免出现空指针异常。
  • 不可变性:构造器注入通常能确保类的依赖关系是不可变的。
缺点:
  • 如果依赖关系较多,构造函数参数过多,可能会导致代码不太易读。

2. 字段注入(Field Injection)

字段注入是直接通过成员变量来注入依赖,Spring通过反射机制将依赖项注入到字段中,而无需显式地调用构造函数或方法。

特点:
  • 简单、直接。
  • 容易实现,但不推荐使用,因为它无法通过构造函数验证依赖关系,可能会导致注入失败或不明显的错误。
使用方法:
  • 只需要在字段上标注@Autowired注解,Spring会自动将对应的Bean注入到字段中。
@Component
public class MyService {

    @Autowired
    private MyRepository myRepository;

    public void performAction() {
        myRepository.saveData();
    }
}
优点:
  • 代码简洁,容易实现。
  • 无需显式定义构造函数或Setter方法。
缺点:
  • 不可测试:字段注入使得类变得不易测试,因为我们无法通过构造函数或方法来明确传入依赖。
  • 耦合性强:使得类的依赖关系不明显,无法明确标识哪些依赖是必需的。
  • 违反封装性:字段注入依赖于Spring容器的反射机制,失去了封装的优势。

3. 方法注入(Setter Injection)

方法注入通过设置方法来注入依赖。Spring容器通过调用Setter方法来注入需要的Bean。

特点:
  • 适用于依赖关系是可选的或可以在Bean的生命周期中修改的情况。
  • 可以通过@Autowired注解标注Setter方法,Spring会自动注入相应的依赖。
使用方法:
  • 在Setter方法上加上@Autowired注解,Spring会自动调用该方法并注入依赖。
@Component
public class MyService {

    private MyRepository myRepository;

    @Autowired
    public void setMyRepository(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    public void performAction() {
        myRepository.saveData();
    }
}
优点:
  • 适用于依赖关系可变的场景,可以在对象创建后进行注入。
  • 如果有多个依赖,Setter方法可以逐个注入。
缺点:
  • 不如构造器注入那样强制依赖,可能导致部分依赖未注入,进而影响系统稳定性。
  • 可能导致依赖关系不明确,增加了代码的耦合度。

总结对比:

注入方式适用场景优点缺点
构造器注入依赖关系不可变,且依赖为必需的情况强制依赖、易于测试、不可变性参数较多时不易读,灵活性差
字段注入简单、快速的注入,依赖可选或不复杂的情况简单、代码简洁、实现快速不易测试、依赖关系不明确、耦合度高
方法注入依赖关系可变,依赖为可选的情况适合依赖可变、Setter可重复调用依赖关系不明确、可能导致空指针异常

总结建议:

  • 对于必需依赖,推荐使用构造器注入,因为它强制要求依赖关系的明确性并且不可变。
  • 对于可选依赖,或者在需要某种后期注入的情况下,可以使用Setter方法注入
  • 字段注入虽然代码最简洁,但不推荐用于生产环境,因为它不利于依赖关系的管理和测试。

这些注入方式各有特点,根据不同的应用场景选择最合适的方式可以帮助提高代码的可维护性和可测试性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/940155.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Hive是什么,Hive介绍

官方网站:Apache Hive Hive是一个基于Hadoop的数据仓库工具,主要用于处理和查询存储在HDSF上的大规模数据‌。Hive通过将结构化的数据文件映射为数据库表,并提供类SQL的查询功能,使得用户可以使用SQL语句来执行复杂的​MapReduce任…

GIN

gin是什么 Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架。 它具有类似 Martini 的 API,但性能比 Martini 快 40 倍。如果你需要极好的性能,使用 Gin 吧。 特点:gin是golang的net/http库封装的web框架,api友好,注…

初始Python篇(13)—— 模块以及Python中常用的内置模块

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏: Python 目录 模块的概念 模块的导入 包的概念以及使用 主程序运行 Python中常用的内置模块 random模块 time模块 datetime模块 …

时间序列异常值检测方法

文章目录 一、基于统计的方法1.1、标准差1.2、箱线图1.3、Z-Score法 二、基于机器学习算法的方法2.1、K-NN2.2、孤立森林 三、基于密度的方法3.1、LOF3.2、DBSCAN密度聚类 时间序列相关参考文章: 时间序列预测算法—ARIMA 时间序列预测算法—Prophet 时间序列分类任…

8K+Red+Raw+ProRes422分享5个影视级视频素材网站

Hello,大家好,我是后期圈! 在视频创作中,电影级的视频素材能够为作品增添专业质感,让画面更具冲击力。无论是广告、电影短片,还是品牌宣传,高质量的视频素材都是不可或缺的资源。然而&#xff…

顺序表的操作

注意位序和数组下标的关系 插入: 插入的时间复杂度: 最深层语句: 最好情况 最坏情况 平均情况 删除: 查找:

五、windows上vscode构建c/c++环境

1、安装vscode 官网下载界面:https://code.visualstudio.com/Download 请根据电脑系统安装所需版本点击下载链接(一般情况下点击windows按钮即可)鼠标左键双击,即可运行安装程序,点击【确认】;选择安装路径…

Spring实例化的基本流程和Bean处理器

目录 Spring实例化的基本流程 Bean的处理器 Bean工厂后处理器(BeanFactoryPostProcessor) 动态注册beanDefinition Bean后处理器(BeanPostProcessor) Spring实例化的基本流程 在了解处理器之前,要清除spring实例化…

【SH】Ubuntu Server 24搭建Web服务器访问Python程序研发笔记

文章目录 说个问题写个方案一、安装Ubuntu Server二、安装Web服务器采用Nginx服务器 三、安装Python及依赖创建项目虚拟环境 四、安装Python Web框架采用Flask框架创建和运行Flask应用(以后的重点) 五、安装WSGI服务器采用Gunicorn 六、配置Nginx七、验证…

109.【C语言】数据结构之求二叉树的高度

目录 1.知识回顾:高度(也称深度) 2.分析 设计代码框架 返回左右子树高度较大的那个的写法一:if语句 返回左右子树高度较大的那个的写法二:三目操作符 3.代码 4.反思 问题 出问题的代码 改进后的代码 执行结果 1.知识回顾&#xf…

瑞吉外卖项目学习笔记(二)Swagger、logback、表单校验和参数打印功能的实现

瑞吉外卖项目学习笔记(一)准备工作、员工登录功能实现 文章目录 3 项目组件优化3.1 实现Swagger文档输出3.2 实现logback日志打印3.3 实现表单校验功能3.4 实现请求参数和响应参数的打印 3 项目组件优化 3.1 实现Swagger文档输出 1)在application.yml中增加knife4…

OpenEuler 22.03 安装 flink-1.17.2 集群

零:规划 本次计划安装三台OpenEuler 22.03 版本操作系统的服务器,用于搭建 flink 集群。这里使用flink1.17.2 的原因,是便于后续与springboot的整合 服务器名IP地址作用其他应用flink01192.168.159.133主jdk11、flink-1.17.2flink02192.168.…

[数据结构] 链表

目录 1.链表的基本概念 2.链表的实现 -- 节点的构造和链接 节点如何构造? 如何将链表关联起来? 3.链表的方法(功能) 1).display() -- 链表的遍历 2).size() -- 求链表的长度 3).addFirst(int val) -- 头插法 4).addLast(int val) -- 尾插法 5).addIndex -- 在任意位置…

20241220在荣品开发板PRO-RK3566的buildroot下适配gc2093

20241220在荣品开发板PRO-RK3566的buildroot下适配gc2093 2024/12/20 16:00 余顺?PRO-RK3566开发板 挂 gc2093模块。刷 buildroot的预编译固件。 update-pro-rk3566-buildroot-hdmi-20231130-034633.img 1、现在发现 qcamera的 拍照Capture、Record录像模式都是640x480分辨率…

实习冲刺数据库练习-01 基础查询

原题链接:牛客网在线编程_SQL篇_非技术快速入门 数据表示例: 根据数据表示例要求我们完成以下查询: (1)获取用户信息表中所有的数据,请你取出相应结果 (2)获取用户的设备id对应的…

【Mars3d】设置backgroundImage、map.scene.skyBox、backgroundImage来回切换

相关链接: http://mars3d.cn/editor-vue.html?keyex_1_2_1&idmap/other/backgroundImg 实现代码: export function show1() {map.setOptions({scene: {backgroundType: "image",backgroundImage: "url(//data.mars3d.cn/img/busin…

telnet命令检查端口

1、简介 telnet是一种用于远程登录的协议,可以通过telnet客户端连接到远程主机,并在远程主机上执行命令。 2、使用telnet命令检查端口 2.1 进入linux终端 2.2 输入telnet命令 如果没有安装telnet命令,请执行以下命令安装 sudo yum install…

Unity 根据文本宽度自动移动图像位置

游戏中有时候需要变动的显示一个物品的数量,变化的文本宽度不停的变化,这时候需要将物品的icon随着文本的长度而改变位置。 实现思路:使用Content Size Fitter来动态改变内容的大小。 首先建立一个文本组件,添加Content Size Fi…

基于Springboot人口老龄化社区服务与管理平台【附源码】

基于Springboot人口老龄化社区服务与管理平台 效果如下: 系统登陆页面 系统主页面 社区信息页面 社区文件页面 活动报名页面 走访任务管理页面 社区资讯页面 老人信息管理页面 研究背景 随着社会老龄化的加剧,老年人口比例逐渐增加,对老年…

加密数据库在现代企业中的应用实践

以下是对加密数据库在现代企业中的应用实践的详细阐述: 一、加密数据库的应用背景 随着信息技术的飞速发展,现代企业对于数据的安全性和隐私保护要求越来越高。数据库作为存储大量敏感信息的关键设施,其安全性直接关系到企业的商业利益和声誉…