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

final修饰的变量必须要在定义时初始化, 或者在构造方法中对其进行初始化.
- 注入的对象可被修改.
在程序执行时, 通过调用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. 构造方法的优点
-
可以注入给final修饰的引用

-
符合单一设计原则
在一次注入中, 只针对一个Bean. -
注入对象不会被改变
由于构造方法只会执行一次, 所以注入的对象不会被改变 -
注入对象会被完全初始化
因为依赖对象的传递是在构造方法中执行的, 而构造方法是在对象创建之初执行的, 所以构造方法注入确保在对象被创建的时候,所有必要的依赖关系都被传递进来并初始化。
举例来说,如果有一个类 A, 它的构造方法接受一个类 B 的对象作为参数, 那么在创建 A 的对象时, 类 B的对象就是被传递的依赖关系, 并且在 A 的构造方法中对 B 的对象进行了初始化. 这确保了在使用 A 的对象时, A 依赖的对象 B是已经准备好并初始化的。
- 通用性更好
构造方法注入可适用非 IoC 框架. 对于IoC框架和非IoC框架. 构造方法注入的代码都是通用的, 所以它的通用性更好.
总结
综上, 依赖注入的实现方式有以上三种. 分别是属性注入, Setter注入和构造方法注入.
属性注入的写法最简单, 使用频率最高. 但缺点也很明确.
Setter注入适用于注入可变对象的场景.
构造方法注入是Spring官方最推荐的注入方法. 明显优势是可以注入对象给final修饰的引用. 通用性更好.
补充
在进行类注入时, 除了使用@Autowired注解之外, 还可以使用@Resource进行注入.
@Aurowired注解和@Resource注解的区别
- 来源不同
@Autowired注解是Spring框架提供的. 而Resource是JDK提供的, 可以在非Spring的环境下使用 - 参数不同
相比于@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;}
- 查找Bean方式不同
@Autowired查找Bean会先根据类型(类名)进行查找, 如果一个类型中有多个Bean, 则会根据对象名来进行匹配.
@Resource查找Bean则是先根据对象名来进行查找, 然后再根据类型来进行查找
也可以参考上面参数不同里面的方式进行查找设置. - 使用范围不同
@Autowired可以用于以上三种注入方式
但@Resource不适用于构造方法注入. - 可选性不同
@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遇到下面这种元素: <th id"demo id" class"value1 value2 value3 ">1、虽然id一般不会有空格,但是前端错误的这种写法(如下图),会造成使用id定位不到元素,如: find…...
gma 空间绘图实战(1):绘制多个子图,连接并展示局部放大区域
安装 gma:pip install gma 本文基于:gma 2.0.3,Python 3.10 本文用到的矢量数据为:CTAmap 1.12。来源于 https://www.shengshixian.com/ 。(感谢锐多宝) 绘图目标 参考代码 import matplotlib.pyplot as p…...
Unity中C#使用协程控制Shader材质变化
文章目录 前言一、协程是什么二、在Unity中使用协程1、我们在 Start 中测试一下协程的执行顺序2、我们实现一个点击按钮实现角色受击效果 三、协程中的动画过渡1、首先,在协程内实现中毒并且消散的效果2、在 OnGUI 内,给一个新按钮使用刚刚定义的协程 四…...
WordPress禁止显示指定类别的文章
使用wordpress禁止输出指定类别的文章可以给get_posts()函数传个数组参数,如下: <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 只是比较简单的解释,在实际使用中,如果遇到需要深入研究的场景,再翻阅相关资料深入研究下。 一、泛型T 这个T在实际使用中很常见,比如List<T>。其实我们还…...
C语言——指针(五)
📝前言: 上篇文章C语言——指针(四)更加深入的介绍了不同类型指针的特点,这篇文章主要想记录一下函数与指针的结合运用以及const和assert关于指针的用法: 1,函数与指针 2,const 3&am…...
文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《考虑气电联合需求响应的气电综合能源配网系统协调优化运行》
这个标题涉及到一个涉及气体(天然气)和电力的综合能源配网系统,并且强调了考虑气电联合需求响应的协调优化运行。让我们逐步解读: 气电综合能源配网系统: 这指的是一个结合了气体(通常是天然气)…...
PostgreSQL 主键和唯一键的区别
主键和唯一键的区别 主键(Primary Key): 主键是用于唯一标识表中的每一条记录的键。主键必须是唯一的,不允许为空。一个表只能有一个主键。主键可以由一个或多个字段组成。主键的值在整个表中必须是唯一的,用于确保数据…...
删除表格中的所有绘图
Ctrl G 调出定位的对话框再点击定位条件 按Delete键,删除...
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原理
我是南城余!阿里云开发者平台专家博士证书获得者! 欢迎关注我的博客!一同成长! 一名从事运维开发的worker,记录分享学习。 专注于AI,运维开发,windows Linux 系统领域的分享! 本…...
如何对售后服务的全流程进行精细化的管理?
——“如何对售后服务的全流程进行精细化的管理?” ——“售后又是一个十分复杂的过程,仅靠手工或者电子表格记录这些内容,肯定是低效率、易出错的。最好的办法是借助合适的管理工具进行精细化的过程管理。” 假设你购买了一台新的家用电器…...
SAP UI5 walkthrough step2 Bootstrap
我的理解,这就是一个引导指令 1.我们右键打开命令行--执行 ui5 use OpenUI5 2.执行命令:ui5 add sap.ui.core sap.m themelib_sap_horizon 执行完之后,会更新 yaml 文件 3.修改index.html <!DOCTYPE html> <html> <head&…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
