当前位置: 首页 > 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&…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏

一、引言 在深度学习中&#xff0c;我们训练出的神经网络往往非常庞大&#xff08;比如像 ResNet、YOLOv8、Vision Transformer&#xff09;&#xff0c;虽然精度很高&#xff0c;但“太重”了&#xff0c;运行起来很慢&#xff0c;占用内存大&#xff0c;不适合部署到手机、摄…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文通过代码驱动的方式&#xff0c;系统讲解PyTorch核心概念和实战技巧&#xff0c;涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...