当前位置: 首页 > news >正文

Spring 依赖注入的三种方式优缺点

小王学习录

  • 前言
  • 属性注入
    • 1. 属性注入的优点
    • 2. 属性注入的缺点
  • Setter注入
    • Setter注入的优点
    • Setter注入的缺点
  • 构造方法注入
    • 1. 构造方法的优点
  • 总结
  • 补充
    • @Aurowired注解和@Resource注解的区别

前言

在前面的文章中介绍了基于注解的方式将Bean存储到Spring中, 接下来介绍如何基于注解的方式从Spring中取对象, 也就是实现DI依赖注入. 本篇文章将会介绍三种依赖注入的方式, 分别是属性注入, Setter注入构造方法注入. 并介绍其各自优缺点.

属性注入

属性注入要用到注解@Autowired

@Controller
public class UseController {@Autowiredprivate UseService useService;public void print(){System.out.println("do_useController");useService.print();}
}

使用@Autowired自动注入, 就是去Spring容器中找到UseService类的Bean对象. 如果Bean对象只有一个, 则直接将对象注入给useService引用. 如果Bean对象有多个, 则根据引用的名字来进行匹配.

在这里插入图片描述

1. 属性注入的优点

属性注入最大的优点就是使用简单, 只需要添加一个@Autowited注解即可.

2. 属性注入的缺点

  1. 属性注入不能注入给一个final修饰的引用.
    在这里插入图片描述原因是final修饰的变量必须要在定义时初始化, 或者在构造方法中对其进行初始化.
  2. 属性注入的通用性差, 只能用于IoC容器中.
  3. 属性注入违背单一设计原则的可能性大
    所谓单一设计原则, 就是一个类只用来完成一个功能.
    属性注入的方式使用起来非常简单, 因此程序员很可能在一个类中注入多个对象. 从而使得这个类的单一设计原则被破坏. 因此说属性输入会使程序违背单一设计原则的概率加大.

Setter注入

@Controller
public class UseController {private UseService useService;@Autowiredpublic void setUseService(UseService useService){this.useService = useService;}public void print(){System.out.println("do_useController");useService.print();}
}

使用setter注入, 通过@Autowired从Spring中取出UseService Bean, 作为实参传给setUseService, 然后在setUseService中将其赋值给引用.

Setter注入的优点

在Setter注入中, 每个Setter只针对一个Bean, 所以他符合单一设计原则.

Setter注入的缺点

  1. 不能注入给一个final修饰的引用
    在这里插入图片描述

final修饰的变量必须要在定义时初始化, 或者在构造方法中对其进行初始化.

  1. 注入的对象可被修改.
    在程序执行时, 通过调用setUseService方法, 可以对注入的对象进行修改.

构造方法注入

@Controller
public class UseController {private UseService useService;@Autowiredpublic UseController(UseService useService) {this.useService = useService;}public void print(){System.out.println("do_useController");useService.print();}}

如果类中只有一个构造方法时, @Autowired可以省略. 这是因为Spring官方推荐构造方法的使用, 所以在底层会自动实现@Autowired

1. 构造方法的优点

  1. 可以注入给final修饰的引用
    在这里插入图片描述

  2. 符合单一设计原则
    在一次注入中, 只针对一个Bean.

  3. 注入对象不会被改变
    由于构造方法只会执行一次, 所以注入的对象不会被改变

  4. 注入对象会被完全初始化
    因为依赖对象的传递是在构造方法中执行的, 而构造方法是在对象创建之初执行的, 所以构造方法注入确保在对象被创建的时候,所有必要的依赖关系都被传递进来并初始化。

举例来说,如果有一个类 A, 它的构造方法接受一个类 B 的对象作为参数, 那么在创建 A 的对象时, 类 B的对象就是被传递的依赖关系, 并且在 A 的构造方法中对 B 的对象进行了初始化. 这确保了在使用 A 的对象时, A 依赖的对象 B是已经准备好并初始化的。

  1. 通用性更好
    构造方法注入可适用非 IoC 框架. 对于IoC框架和非IoC框架. 构造方法注入的代码都是通用的, 所以它的通用性更好.



总结

综上, 依赖注入的实现方式有以上三种. 分别是属性注入, Setter注入和构造方法注入.

属性注入的写法最简单, 使用频率最高. 但缺点也很明确.
Setter注入适用于注入可变对象的场景.
构造方法注入是Spring官方最推荐的注入方法. 明显优势是可以注入对象给final修饰的引用. 通用性更好.

补充

在进行类注入时, 除了使用@Autowired注解之外, 还可以使用@Resource进行注入.

@Aurowired注解和@Resource注解的区别

  1. 来源不同
    @Autowired注解是Spring框架提供的. 而Resource是JDK提供的, 可以在非Spring的环境下使用
  2. 参数不同
    相比于@Autowired来说, @Resource支持更多的参数配置
    如Resource可以通过name参数来指定具体的Bean名称.
    但是@Autowired可以使用另一个注解@Qualifier注解来指定具体的Bean名称

比如现在有Dog和Cat两个类都实现了Animal接口. 当要依赖注入一个Animal Bean时, 可以通过@Qualifier注解来显式指定要注入的是哪个Bean(注意: @Qualifier不适合于构造方法注入)

@Component
public class Zoo {@Autowired@Qualifier("dog")private Animal animal;}
  1. 查找Bean方式不同
    @Autowired查找Bean会先根据类型(类名)进行查找, 如果一个类型中有多个Bean, 则会根据对象名来进行匹配.
    @Resource查找Bean则是先根据对象名来进行查找, 然后再根据类型来进行查找
    也可以参考上面参数不同里面的方式进行查找设置.
  2. 使用范围不同
    @Autowired可以用于以上三种注入方式
    但@Resource不适用于构造方法注入.
  3. 可选性不同
    @Autowired 可以设置非非必需, 即如果找不到匹配的Bean, 属性可以为null. 但可以使用@Autowire(required = true)来设置为必需的(默认为必须).
    @Resource 默认是必需的, 不支持可选性. 如果找不到匹配的Bean, 会抛出异常.
    在这里插入图片描述

总而言之, @Autowired 更为灵活, 而 @Resource 更加标准化, 可以跨平台使用.

相关文章:

Spring 依赖注入的三种方式优缺点

小王学习录 前言属性注入1. 属性注入的优点2. 属性注入的缺点 Setter注入Setter注入的优点Setter注入的缺点 构造方法注入1. 构造方法的优点 总结补充Aurowired注解和Resource注解的区别 前言 在前面的文章中介绍了基于注解的方式将Bean存储到Spring中, 接下来介绍如何基于注解…...

代理模式介绍(静态代理、jdk动态代理、cglib代理)

一、静态代理 (一)定义 1、定义 为其他对象提供一种代理以控制对这个对象的访问; 2、涉及到的角色 (1)抽象主题角色:真实主题和代理主题的共同接口,便于在使用真实主题的地方都可以使用代理…...

设计模式基础——工厂模式剖析(2/2)

目录 一、工厂模式 1.1 工厂模式的定义 1.2 工厂模式的设计意图 1.3 工厂模式主要解决的问题 1.4 工厂模式的缺点 1.5 实际的应用案例 1. 数据库连接池 2. 图形用户界面(GUI)组件 3. 文件操作 二、各种工厂模式的变形 1.1 简单工厂模式&#…...

spark3.x 读取hudi报错

报错信息如下: Exception in thread "main" org.apache.hudi.exception.HoodieUpsertException: Failed to upsert for commit time 20231201203145254 at org.apache.hudi.table.action.commit.BaseWriteHelper.write(BaseWriteHelper.java:64) at org.apa…...

微信小程序中block和View组件的使用区别

block和View组件都是用于布局的组件: 1. Block组件: Block组件是一个无实际显示效果的组件,它主要用于包裹一组组件,并提供了类似于div的作用。使用Block组件可以将一组组件进行分组,便于样式的管理和控制。Block组件不会在页面…...

代码混淆技术探究与工具选择

代码混淆技术探究与工具选择 引言 在软件开发中,保护程序代码的安全性是至关重要的一环。代码混淆(Obfuscated code)作为一种常见的保护手段,通过将代码转换成难以理解的形式来提升应用被逆向破解的难度。本文将介绍代码混淆的概…...

selenium 解决 id定位、class定位中,属性值带空格的解决办法

一、前置说明 selenium遇到下面这种元素&#xff1a; <th id"demo id" class"value1 value2 value3 ">1、虽然id一般不会有空格&#xff0c;但是前端错误的这种写法(如下图)&#xff0c;会造成使用id定位不到元素&#xff0c;如&#xff1a; find…...

gma 空间绘图实战(1):绘制多个子图,连接并展示局部放大区域

安装 gma&#xff1a;pip install gma 本文基于&#xff1a;gma 2.0.3&#xff0c;Python 3.10 本文用到的矢量数据为&#xff1a;CTAmap 1.12。来源于 https://www.shengshixian.com/ 。&#xff08;感谢锐多宝&#xff09; 绘图目标 参考代码 import matplotlib.pyplot as p…...

Unity中C#使用协程控制Shader材质变化

文章目录 前言一、协程是什么二、在Unity中使用协程1、我们在 Start 中测试一下协程的执行顺序2、我们实现一个点击按钮实现角色受击效果 三、协程中的动画过渡1、首先&#xff0c;在协程内实现中毒并且消散的效果2、在 OnGUI 内&#xff0c;给一个新按钮使用刚刚定义的协程 四…...

WordPress禁止显示指定类别的文章

使用wordpress禁止输出指定类别的文章可以给get_posts()函数传个数组参数&#xff0c;如下&#xff1a; <div class"widget" id"diary1"> <h3>随机呈现</h3> <ul> <?php $argsarray( numberposts>16, category>-9,-12, …...

C#里面的泛型(T),泛型类,泛型方法,泛型接口等简单解释

https://blog.csdn.net/dap769815768/article/details/81946506 只是比较简单的解释&#xff0c;在实际使用中&#xff0c;如果遇到需要深入研究的场景&#xff0c;再翻阅相关资料深入研究下。 一、泛型T 这个T在实际使用中很常见&#xff0c;比如List<T>。其实我们还…...

C语言——指针(五)

&#x1f4dd;前言&#xff1a; 上篇文章C语言——指针&#xff08;四&#xff09;更加深入的介绍了不同类型指针的特点&#xff0c;这篇文章主要想记录一下函数与指针的结合运用以及const和assert关于指针的用法&#xff1a; 1&#xff0c;函数与指针 2&#xff0c;const 3&am…...

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《考虑气电联合需求响应的气电综合能源配网系统协调优化运行》

这个标题涉及到一个涉及气体&#xff08;天然气&#xff09;和电力的综合能源配网系统&#xff0c;并且强调了考虑气电联合需求响应的协调优化运行。让我们逐步解读&#xff1a; 气电综合能源配网系统&#xff1a; 这指的是一个结合了气体&#xff08;通常是天然气&#xff09;…...

PostgreSQL 主键和唯一键的区别

主键和唯一键的区别 主键&#xff08;Primary Key&#xff09;&#xff1a; 主键是用于唯一标识表中的每一条记录的键。主键必须是唯一的&#xff0c;不允许为空。一个表只能有一个主键。主键可以由一个或多个字段组成。主键的值在整个表中必须是唯一的&#xff0c;用于确保数据…...

删除表格中的所有绘图

Ctrl G 调出定位的对话框再点击定位条件 按Delete键&#xff0c;删除...

Linux卸载Nginx

1、停止Nginx软件 #/usr/local/nginx/sbin/nginx-sstop 或者kill进程 #ps -ef|grep nginx #kill -9 PID 2、查找根下所有名子包含nginx的文件 #sudofind/-namenginx* 3、执行命令删掉nignx安装的相关文件 # rm -rf /usr/local/sbin/nginx # rm -rf /usr/local/nginx # r…...

Qt之QGraphicsView —— 笔记1:绘制简单图元(附完整源码)

效果 相关类介绍 QGraphicsView类提供了一个小部件,用于显示QGraphicsScene的内容。QGraphicsView在可滚动视口中可视化。QGraphicsView将滚动其视口,以确保该点在视图中居中。 QGraphicsScene类 提供了一个用于管理大量二维图形项的场景。请注意,QGraphicsScene没有自己的视…...

SpringIoC原理

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 本…...

如何对售后服务的全流程进行精细化的管理?

——“如何对售后服务的全流程进行精细化的管理&#xff1f;” ——“售后又是一个十分复杂的过程&#xff0c;仅靠手工或者电子表格记录这些内容&#xff0c;肯定是低效率、易出错的。最好的办法是借助合适的管理工具进行精细化的过程管理。” 假设你购买了一台新的家用电器…...

SAP UI5 walkthrough step2 Bootstrap

我的理解&#xff0c;这就是一个引导指令 1.我们右键打开命令行--执行 ui5 use OpenUI5 2.执行命令&#xff1a;ui5 add sap.ui.core sap.m themelib_sap_horizon 执行完之后&#xff0c;会更新 yaml 文件 3.修改index.html <!DOCTYPE html> <html> <head&…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

Qt的学习(一)

1.什么是Qt Qt特指用来进行桌面应用开发&#xff08;电脑上写的程序&#xff09;涉及到的一套技术Qt无法开发网页前端&#xff0c;也不能开发移动应用。 客户端开发的重要任务&#xff1a;编写和用户交互的界面。一般来说和用户交互的界面&#xff0c;有两种典型风格&…...

python读取SQLite表个并生成pdf文件

代码用于创建含50列的SQLite数据库并插入500行随机浮点数据&#xff0c;随后读取数据&#xff0c;通过ReportLab生成横向PDF表格&#xff0c;包含格式化&#xff08;两位小数&#xff09;及表头、网格线等美观样式。 # 导入所需库 import sqlite3 # 用于操作…...

【字节拥抱开源】字节团队开源视频模型 ContentV: 有限算力下的视频生成模型高效训练

本项目提出了ContentV框架&#xff0c;通过三项关键创新高效加速基于DiT的视频生成模型训练&#xff1a; 极简架构设计&#xff0c;最大化复用预训练图像生成模型进行视频合成系统化的多阶段训练策略&#xff0c;利用流匹配技术提升效率经济高效的人类反馈强化学习框架&#x…...