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

小王学习录

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

前言

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

属性注入

属性注入要用到注解@Autowired

@Controller
public class UseController {
    @Autowired
    private 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;
    @Autowired
    public 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;
    @Autowired
    public 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 更加标准化, 可以跨平台使用.

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

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

相关文章

银河麒麟安装lnmp,安装chrome。

银河麒麟下载地址 兆芯 arm 架构64 点击下载 安装lnmp 下载相关文件 链接:https://pan.baidu.com/s/1YqFLfGpE5DP3Sf_2GsXqNg?pwdptsn –来自百度网盘超级会员V7的分享 上传到服务器 我所选择上传的地方是 /home/npf/nginx-server, php放在跟nginx-…

vim常见操作

vim常见操作 文章目录 vim常见操作1. 回退/前进2. 搜索3. 删除4. 定位到50行5. 显示行号6. 复制粘贴7. 剪贴8. 替换9. vim打开文件的时候出现 1. 回退/前进 1.esc进入命令模式 2.ctrlr 前进 u 回退2. 搜索 1) esc进入命令模式 2) /text  查找text&am…

第21章:网络通信

21.1 网络程序设计基础 21.1.1 局域网与互联网 为了实现两台计算机的通信,必须用一个网络线路连接两台计算机。如下图所示 21.1.2 网络协议 1.IP协议 IP是Internet Protocol的简称,是一种网络协议。Internet 网络采用的协议是TCP/IP协议&#xff0…

Vue3组件使用问题

Vue3组件学习 文章目录 Vue3组件学习一、Message 全局提示组件返回数据换行问题二、DatePicker 日期选择框组件限制选定年份问题 一、Message 全局提示组件返回数据换行问题 问题&#xff1a;使用中发现仅仅通过写入\n或<br/>&#xff0c;无法实现回车显示的结果。 解决…

彻底解决org.gradle.api.artifacts.DependencySubstitutions

需求背景 最近在使用android studio导入hbuilder的HBuilder-Integrate-AS工程时候报错&#xff0c;错误消息如下两种。 错误描述 第一种 Failed to notify dependency resolution listener. void org.gradle.api.artifacts.DependencySubstitutions$Substitution.with(org.g…

自动数据增广论文笔记 | AutoAugment: Learning Augmentation Strategies from Data

谷歌大脑出品 paper: https://arxiv.org/abs/1805.09501 这里是个论文的阅读心得&#xff0c;笔记&#xff0c;不等同论文全部内容 文章目录 一、摘要1.1 翻译1.2 笔记 二、(第三部分)自动增强:直接在感兴趣的数据集上搜索最佳增强策略2.1 翻译2.2 笔记 三、(第四部分)实验与结…

最小生成树算法与二分图算法

文章目录 概述 P r i m Prim Prim 算法 - 稠密图 - O ( n 2 ) O(n^2) O(n2)思路概述时间复杂度分析AcWing 858. Prim算法求最小生成树CODE K r u s k a l Kruskal Kruskal 算法 - 稀疏图 - O ( m l o g m ) O(mlogm) O(mlogm)思路解析时间复杂度分析AcWing 859. Kruskal算法求…

【Vue第3章】使用Vue脚手架_Vue2_笔记

笔记 脚手架文件结构 ├── node_modules ├── public │ ├── favicon.ico: 页签图标 │ └── index.html: 主页面 ├── src │ ├── assets: 存放静态资源 │ │ └── logo.png │ │── component: 存放组件 │ │ └── HelloWorld.vue …

Linux 多进程并发设计-进程对核的亲缘设置

1设计结构 2 设计优点 1 充分利用多核系统的并发处理能力2 负载均衡3 职责明确&#xff0c;管理进程仅负责管理&#xff0c;工作进程仅负责处理业务逻辑 3 演示代码: //main.cpp #define _GNU_SOURCE #include<sys/types.h> #include<sys/wait.h> #include <…

RflySim | 姿态控制器设计实验二

本实验的目的是让多旋翼的姿态能够跟随我们给定的期望姿态&#xff0c;姿态控制器的好坏直接决定了多旋翼能否平稳飞行。 RflySim| 姿态控制器设计实验二 01 基础实验 1.复现四旋翼飞行器的Simulink仿真&#xff0c;分析控制分配器的作用&#xff1b; 2.记录姿态的阶跃响应&a…

ArcGIS Pro中怎么设置标注换行

在ArcGIS Pro中进行文字标注的时候&#xff0c;如果标注的字段内容太长&#xff0c;直接标注的话会不美观&#xff0c;而且还会影响旁边的标注显示&#xff0c;这里为大家介绍一下在ArcGIS Pro中设置文字换行的方法&#xff0c;希望能对你有所帮助。 数据来源 本教程所使用的…

基于java斗车交易系统设计与实现论文

摘 要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;科学化的管理&#xff0c;使信息存…

PCL 点云最小二乘法拟合二维圆

文章目录 一、原理概述二、实现代码三、实现效果参考资料一、原理概述 二、实现代码 // 标准文件 #include <iostream>// PCL #include <pcl/io/pcd_io.h>

c++ redis客户端, 带详情输入输出

文章目录 使用方法输入输出解释代码输出 使用方法 g main.cpp ./a.out -h 127.0.0.1 -p 6379 输入 一行内输入 redis 命令 keys* set name get name 等等 redis命令 输出解释 输入redis: redis收到的redis协议的数据 human输入&#xff1a; 你输入的原始字符 redis输出&#xf…

【Ambari】Python调用Rest API 获取YARN HA状态信息并发送钉钉告警

&#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&am…

SSL证书代理

众所周知&#xff0c;SSL证书已经成为当下网络安全中不可或缺的一个环节&#xff0c;对于很多开发公司来说&#xff0c;给自己的客户提供SSL证书安全服务也是最为基础的。 但是目前市面上像阿里云之类的证书服务商对于开发公司需要的证书并没有太大的一个优惠政策&#xff0c;给…

Java第二十一章总结

网络编程三要素 ip地址&#xff1a;计算机在网络中的唯一标识 端口&#xff1a;应用程序在计算机中唯一标识 协议&#xff1a;通信协议&#xff0c;常见有UDP和TCP协议 InetAddress类 表示Internet协议地址 //返回InetAddress对象 InetAddress byName InetAddress.…

2023年4K投影仪怎么选?极米H6 4K高亮版怎么样?

随着人们生活水平的不断提升&#xff0c;投影仪也逐渐成为了家家户户的必备家居好物。近十年来&#xff0c;中国投影仪市场规模增长数倍&#xff0c;年均增长率大幅提高。从近10年的发展趋势来看&#xff0c;投影仪行业处于高速发展期。 此前&#xff0c;极米科技推出的极米H6…

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

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