【框架篇】对象注入的三种实现方式

在这里插入图片描述

对象注入的实现

一,实现方式的使用

对象注入也可被称为对象装配,是把Bean对象获取出来放到某个类中。

对象注入的实现方式有3种,分别为属性注入,Setter注入和构造方法注入。

为了更好地理解对象注入的实现方式,搞个实例来具体说明:

1.0,前期准备

1,准备Service类

@Service
public class StudentService {
    public void sayHi(){
        System.out.println("do student service sayHi()");
    }
}

示例问题:将 Service 类注入到 Controller 类中,对象注入实现:

1.1,属性注入

1,方式对应实现的Controller 类代码:

@Controller
public class StudentController {
    //注入方式:属性注入
    @Autowired
    private StudentService studentService;
    public void sayHi(){
        System.out.println("do student controller sayHi()");
        studentService.sayHi();
    }
}

2,启动类实现代码:

public class App {
    public static void main(String[] args) {
        //1,获取Spring上下文
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2,得到Bean对象
        StudentController studentController =
                applicationContext.getBean("studentController",StudentController.class);
        //3,使用Bean对象
        studentController.sayHi();
    }
}

3,启动类执行结果:

1.2,Setter注入

1,方式对应实现的Controller 类代码:

@Controller
public class StudentController {
    private StudentService studentService;
    @Autowired
    public void setStudentService(StudentService studentService) {
        this.studentService = studentService;
    }
    public void sayHi(){
        System.out.println("do student controller sayHi()");
        studentService.sayHi();
    }
}

2,启动类实现代码:

public class App {
    public static void main(String[] args) {
        //1,获取Spring上下文
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2,得到Bean对象
        StudentController studentController =
                applicationContext.getBean("studentController",StudentController.class);
        //3,使用Bean对象
        studentController.sayHi();
    }
}

3,启动类执行结果:

image-20230710103836173

1.3,构造方法注入

1,方式对应实现的Controller 类代码:

@Controller
public class StudentController {
    private StudentService studentService;
    @Autowired
    public StudentController(StudentService studentService) {
        this.studentService = studentService;
    }
    public void sayHi(){
        System.out.println("do student controller sayHi()");
        studentService.sayHi();
    }
}

2,启动类实现代码:

public class App {
    public static void main(String[] args) {
        //1,获取Spring上下文
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2,得到Bean对象
        StudentController studentController =
                applicationContext.getBean("studentController",StudentController.class);
        //3,使用Bean对象
        studentController.sayHi();
    }
}

3,启动类执行结果:

image-20230710103841006


二,方式的优缺点分析

2.1,属性注入

1,方式实现代码:

image-20230710104809219

2,方式优点:

  • 实现简单,易于理解和维护

3,方式缺点:

  • 不能注入不可变对象【final 修饰的变量】
  • 通用性差,只适用于IoC容器,在非IoC框架中无效
  • 更容易违背单一设计原则

2.2,Setter注入

1,方式实现代码:

image-20230710105024612

2,方式优点:

  • 符合单一设计原则【每个方法只传递一个对象】

3,方式缺点:

  • 不能注入不可变对象【final 修饰的变量】

  • 使用Setter注入的对象可能被修改

2.3,构造方法注入

1,方式实现代码:

image-20230710105124339

注意:如果只有一个构造方法,那么 @Autowired 注解可以省略。

2,方式优点:

  • 可以注入不可变对象【final 修饰的变量】

  • 注入对象不会被改变【构造方法只执行一次】

  • 注入对象会完全被初始化

  • 通用性更好,可在IoC容器中使用,也可在非IoC中使用

3,方式缺点:

  • 不符合单一设计原则【每个方法可传递多个对象】

三,对象注入中的问题

3.1,@Autowired 和 @Resource

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

image-20230710111811566

@Autowired@Resource 都是在 Spring 框架中用于注入依赖的注解,它们有以下区别:

  1. 来源不同:
    • @Autowired 是 Spring 框架提供的注解,通过类型进行依赖注入。
    • @Resource 是 JavaEE 定义的注解,通过名称进行依赖注入。
  2. 注入方式不同:
    • @Autowired 默认按照类型匹配的方式进行注入,如果存在多个相同类型的实例,可以结合 @Qualifier 注解来指定具体实例。
    • @Resource 默认按照名称匹配的方式进行注入,它支持使用 nametype 属性来指定名称或类型进行匹配。
  3. 支持的类型不同:
    • @Autowired 支持通过构造方法注入、属性注入、Setter 注入的方式实现依赖注入。
    • @Resource 支持通过属性注入、Setter 注入的方式实现依赖注入,不支持构造方法注入。
  4. 应用范围不同:
    • @Autowired 主要用于 Spring 框架中的组件(如 Spring Bean)的依赖注入。
    • @Resource 是 JavaEE 规范中的注解,它可以用于依赖注入和资源的获取,对于不依赖于 Spring 框架的应用也可以使用。

3.2,同⼀类型多个 @Bean 报错

当出现多个 Bean 返回同⼀对象类型时,程序会报错。解决同一个类型,多个bean的解决方案有以下两个:

1,使用 @Resource(name="")

image-20230710113255725

2,搭配 @Autowired 使用 @Qualifierr(value = "")

image-20230710113416657


核心总结

1,三种对象注入的实现方式以及优缺点?

属性注入,Setter注入和构造方法注入是在依赖注入中常用的三种方式,它们各有优缺点:

1,属性注入方式:其实现简单,易于理解和维护,但是其不能注入不可变对象,只适用于IoC容器,并且违反单一设计原则的概率大。

2,Setter注入方式:其符合单一设计原则,但是其不能注入不可变对象,并且使用Setter注入的对象可能被修改。

3,构造方法注入方式:其可以注入不可变对象,注入的对象不能被改变,保证注入对象完全被初始化,并且具有通用性,但是其不符合单一设计原则。

注意:在上述的三种对象注入的实现方式中,构造方法注入是Spring推荐的注入方式。


思考:为什么构造方法可以注入不可变变量,而属性注入和Setter注入却不行呢?

解答:在 Java 中,被final修饰的对象,要么直接进行赋值,要么就在构造方法中进行赋值,两种情况必须满足一个,否则方式报错。


2,@Autowired 和 @Resource 注入注解的区别?

@Autowired@Resource 都是在 Spring 框架中用于注入依赖的注解,它们有以下区别:

1,来源不同:@Autowired 是 Spring 框架提供的注解,而@Resource 是 JavaEE 定义的注解。

2,注入方式不同:@Autowired 默认按照类型匹配的方式进行注入,而@Resource 默认按照名称匹配的方式进行注入。

3,支持的类型不同:@Resource 支持通过属性注入、Setter 注入的方式实现依赖注入,不支持构造方法注入,而@Autowired 支持。

4,应用范围不同:@Autowired 主要用于 Spring 框架中的组件的依赖注入,而@Resource对于不依赖于 Spring 框架的应用也可使用。


3,同⼀类型多个 @Bean 报错的解决方案有哪些?

解决同一个类型 @Bean 报错的解决方案有以下两个:

  1. 使用 @Resource(name="")
  2. 使用 @Qualifierr(value = "") 【搭配@Autowired使用】

结语

这就是本期博客的全部内容啦!如果有什么其他的问题无法自己解决,可以在评论区留言哦!

最后,如果你觉得这篇文章写的还不错的话或者有所收获的话,麻烦小伙伴们动动你们的小手,给个三连呗(点赞👍,评论✍,收藏📖),多多支持一下!各位的支持是我最大的动力,后期不断更新优质的内容来帮助大家,一起进步。那我们下期见!

在这里插入图片描述


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

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

相关文章

Spring管理事务知识

目录 1.什么是事务 2.事务的特性ACID 3.Spring 管理事务的方式 4.Spring管理事务的体现:JDBCTemplate 5.声明式事务的属性有哪些 6.声明式事务属性---只读 7.声明式事务属性---超时 8.声明式事务属性---回滚策略 9.声明式事务属性---事务隔离级别 10.声明…

1、Kubernetes 概述和架构

目录 一、基本介绍 二、kubernetes功能和架构 2.1、 概述 2.2 、功能 (1)自动装箱 (2)自我修复(自愈能力) (3)水平扩展 (4)服务发现 (5)滚动更新 &a…

【Vue】给 elementUI 中的 this.$confirm、this.$alert、 this.$prompt添加按钮的加载效果

文章目录 主要使用 beforeClose 方法实现 loading 的效果beforeClose MessageBox 关闭前的回调,会暂停实例的关闭 function(action, instance, done)1. action 的值为confirm, cancel或close。 2. instance 为 MessageBox 实例,可以通过它访问实例上的属…

C语言中定义和声明的区别

声明(declaration)与定义(definition) 为了使不同的文件都可以访问同一个变量,C会区 分变量的声明和定义。 变量的定义会为这个变量分配存储空间,并且 可能 会为其指定一个初始化的值, 一个变量的定义有且 仅有一处。 定义实际上是一种特殊…

【网络】HTTPS协议原理

目录 “加密”相关概念 为什么要加密 常见加密方式 对称加密 非对称加密 HTTPS工作过程探究 方案1-只使用对称加密 方案2-只使用非对称加密 方案3-客户端和服务端双方都使用非对称加密 方案4-非对称加密 对称加密 上述方案问题分析 方案5-证书认证 非对称加密对…

Kafka传输数据到Spark Streaming通过编写程序java、scala程序实现操作

一、案例说明 现有一电商网站数据文件,名为buyer_favorite1,记录了用户对商品的收藏数据,数据以“\t”键分割,数据内容及数据格式如下: 二、前置准备工作 项目环境说明 Linux Ubuntu 16.04jdk-7u75-linux-x64scal…

C++的switch函数用法

一个 switch 语句允许测试一个变量等于多个值时的情况。每个值称为一个 case,且被测试的变量会对每个 switch case 进行检查。 语法 C 中 switch 语句的语法: switch(expression){ case constant-expression : statement(s); break; // 可选的 case c…

解决MAC IDEA终端每次都要source ~/.zshrc

安装nvm之后,发现每隔一段时间(不清楚是新打开一个终端还是会定时刷新)就要重新执行source ~/zshrc,才能执行nvm命令。找了一圈发现idea默认使用的shell是bash,将默认的shell改成zsh就可以,更改位置&#x…

多模态系列论文--CoCa 详细解析

论文地址:CoCa: Contrastive Captioners are Image-Text Foundation Models 代码地址:CoCa CoCa 1 摘要2 网络结构3 损失函数4 实验结果5 总结 1 摘要 CoCa代表Contrastive Captioners的缩写,代表模型用两个目标函数训练出来的,一…

selenium怎么使用代理IP

什么是selenium Selenium 是一个自动化测试框架,用于测试 Web 应用程序的功能性。它支持多个编程语言(如Java,Python,C#等)并且可以在操作系统和不同浏览器上运行测试。Selenium 可以模拟用户在浏览器中的操作&#x…

PyTorch从零开始实现Transformer

文章目录 自注意力Transformer块编码器解码器块解码器整个Transformer参考来源全部代码(可直接运行) 自注意力 计算公式 代码实现 class SelfAttention(nn.Module):def __init__(self, embed_size, heads):super(SelfAttention, self).__init__()self.e…

RDS-Tools RDS-Knight Crack

RDS 高级安全性 利用全面的网络安全工具箱中有史以来最强大的安全功能集来保护您的 RDS 基础架构。 全方位 360 保护 无与伦比的功能集 无与伦比的物有所值 企业远程桌面安全。现代工作空间的智能解决方案。 办公室正在权力下放。远程办公室和移动员工数量创历史新高。随…

机器学习技术(四)——特征工程与模型评估

机器学习技术(四)——特征工程与模型评估(1️⃣) 文章目录 机器学习技术(四)——特征工程与模型评估(:one:)一、特征工程1、标准化2、特征缩放3、缩放有离群值的数据4、非线性转换5、样本归一化6、特征二值化7、标称特征编码(one-…

设计模式——命令模式

命令模式 定义 将一个请求封装成一个对象,从而让你使用不同的请求吧客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。 命令模式是一个高内聚的模式。 优缺点、应用场景 优点 类间解耦。调用者与接收者之间没有任…

Linux系统使用(超详细)

目录 Linux操作系统简介 Linux和windows区别 Linux常见命令 Linux目录结构 Linux命令提示符 常用命令 ls cd pwd touch cat echo mkdir rm cp mv vim vim的基本使用 grep netstat Linux面试题 Linux操作系统简介 Linux操作系统是和windows操作系统是并列…

Github Pages使用自定义域名

Github Pages使用自定义域名 部署好网站后默认访问地址是xxx.github.io,我们想要自定义为自己的域名 1.DNS解析 这里我使用的是腾讯云,DNS解析DNSPod 添加两条解析记录: 第一个解析记录的记录类型为A,主机记录为,记录值为ping 你的github用户名.githu…

【Java】单例模式

单例模式 设计模式概述单例模式实现思路饿汉式懒汉式饿汉式 vs 懒汉式 设计模式概述 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模式免去我们自己再思考和摸索。就像是经典的棋谱,不同的棋局,我…

【unity之IMGUI实践】单例模式管理面板对象【一】

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:uni…

electron globalShortcut 快捷键与系统全局快捷键冲突

用 electron 开发自己的接口测试工具(Post Tools),在设置了 globalShortcut 快捷键后,发现应用中的快捷键与系统全局快捷键冲突了,导致系统快捷键不可正常使用。 快捷键配置 export function initGlobalShortcut(main…

【宝塔】宝塔部署ThinkPHP项目

最近搞了个培训教育的小程序,后端服务用的是ThinkPHP。使用的过程中,发现对于这种小项目用php还是很不错的选择,开发便捷,轻量级。宝塔神器也是很不错的,值得推荐使用。 下面介绍一下项目中用宝塔部署ThinkPHP项目&…