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

news2024/11/17 13:26:13

在这里插入图片描述

对象注入的实现

一,实现方式的使用

对象注入也可被称为对象装配,是把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使用】

结语

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

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

在这里插入图片描述


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

24 MFC文档串行化和单文档应用程序

文章目录 文档串行化全部代码 单文档应用程序搭建原理搭建框架Win32 过度到MFC 三部曲设置ID资源全部代码 单文档应用程序设置标题绘图 简单的管理系统部分代码 文档串行化 ui 设计 保存 void CfileDemoDlg::OnBnClickedBtnSave() {UpdateData();//CFile file(L"Demo.dat…

python+pytest接口自动化(9)-cookie绕过登录(保持登录状态)

目录 cookie工作原理 cookie绕过登录 总结 在编写接口自动化测试用例或其他脚本的过程中,经常会遇到需要绕过用户名/密码或验证码登录,去请求接口的情况,一是因为有时验证码会比较复杂,比如有些图形验证码,难以通过…

旅游信息推荐系统带文档springboot+vue

功能 用户注册和登录:用户可以注册一个账户并登录到系统中。旅游项目展示:系统展示各种旅游项目的信息,包括目的地、行程、费用等。旅游项目搜索和筛选:用户可以搜索和筛选旅游项目,根据目的地、日期、费用等条件。预…

Linux系统终端窗口ctrl+c,ctrl+z,ctrl+d的区别

时常在Linux系统上,执行某命令停不下来,就这几个ctrl组合键按来按去,今天稍微总结下具体差别,便于以后linux系统运维操作 1、ctrlc强制中断程序,相应进程会被杀死,中断进程任务无法恢复执行 2、ctrlz暂停正…

mongodb集群搭建

下载地址: https://www.mongodb.com/try/download/community下载mongodb-linux-x86_64-rhel70-5.0.18 搭建集群 tar -zxvf mongodb-linux-x86_64-rhel70-5.0.18.tgz mkdir -p data/dp cd mongodb-linux-x86_64-rhel70-5.0.18 mkdir -p data/db mkdir log mkdir c…

Ubuntu 23.04安装最新版本Halcon 23.05

Ubuntu 23.04安装最新版本Halcon 23.05 官网下载安装环境变量设置创建快捷方式给个最新ubuntu的镜像源地址 官网下载 去Halcon官网:https://www.mvtec.com/products/halcon/,注册或登录,点击Download: 或者进入大恒网站&#xf…

Ubuntu最新版本23.05配置Flameshot(途中解决疑难杂症)

Ubuntu最新版本23.05配置Flameshot截图软件 安装方法:添加Ubuntu的快捷键遇到的问题解决 安装方法: sudo apt install flameshot出现该页面表示成功: 可以直接在终端输入:flameshot gui flameshot gui进行截图。 添加Ubuntu的…

云计算与大数据——MPI集群配置

什么是MPI集群? MPI(消息传递接口)是一种用于编写并行程序的标准,它允许在多个计算节点上进行通信和协作。MPI集群配置是指在一个或多个计算节点上设置MPI环境以实现并行计算。 MPI集群配置的步骤: 硬件选型&#x…

三菱PLC上位机测试

利用三菱的MX Component与三菱PLC进行以太网通信,我们可以用官方的dll编写C#代码,特别简单,最后附上整个源码下载。 1. 安装MX Component(必须)和GX WORKS3(主要是仿真用,实际可以不装&#xf…

空间光通信-调制解调滤波与同步

图文并茂,讲解电磁波传播原理_哔哩哔哩_bilibili 深入浅出空间光通信-3.调制解调滤波与同步_哔哩哔哩_bilibili 傅里叶变换这样学,何愁不会呢?直观理解傅里叶变换_哔哩哔哩_bilibili 第二十三课:声音编辑必看!&…

【六袆 - windows】windows计划任务,命令行执行,开启计划任务,关闭计划任务,查询计划任务

windows计划任务 查看 Windows 自动执行的指令取消 Windows 中的计划任务启动执行计划任务 查看 Windows 自动执行的指令 您可以使用以下方法: 使用任务计划程序:任务计划程序是 Windows 内置的工具,可以用于创建、编辑和管理计划任务。您可…

pytest+allure运行出现乱码的解决方法

pytestallure运行出现乱码的解决方法 报错截图: 这是因为没有安装allure运行环境或者没有配置allure的环境变量导致,解决方案: 1.安装allure运行环境 官方下载地址:https://github.com/allure-framework/allure2/releases 百度…

JavaSE - 内部类

目录 final定义常量 1. 内部类 1.1 实例内部类 1.1.1 如何获取实例内部类的对象 1.1.2 实例内部类中不能有静态的成员变量 1.1.3 实例内部类方法中可以直接访问外部类中的任何成员 1)在实例内部类方法中访问同名的成员时,优先访问自己的&#xff0…

nacos注册中心+Ribbon负载均衡+完成openfeign的调用

目录 1.注册中心 1.1.nacos注册中心 1.2. 微服务注册和拉取注册中心的内容 2.3.修改订单微服务的代码 3.负载均衡组件 3.1.什么是负载均衡 3.2.什么是Ribbon 3.3.Ribbon 的主要作用 3.4.Ribbon提供的负载均衡策略 4.openfeign完成服务调用 4.1.什么是OpenFeign 4.2…

5.2 Python高阶特性之---切片迭代

一、 切片 一般用于提取指定区间内的内容,常用于:str、list、tuple等类型的的局部变量,如下为具体案例1、 【列表切片】 res_list [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]1) 无步长: …

C++——类的六大默认成员构造函数

文章目录 1.默认成员函数思维导图2.构造函数定义特性 2.析构函数定义特性 3.拷贝构造函数定义特性 4.赋值构造函数定义特性 5.重载取地址运算符定义特性 6.重载const取地址运算符定义特性 1.默认成员函数思维导图 2.构造函数 定义 在面向对象编程中,构造函数是一种…

RHCSA——Linux网络、磁盘及软件包管理

ZY目录 Linux操作系统讲解:一、网络管理1、NetworkManager1.1、nmtui界面:1.2、nmcli使用方法: 2、配置网络2.1、网络接口以及网络连接2.2、配置方法:2.3、ping命令:2.4、wget命令 二、磁盘管理2.1、分区得两种格式2.1…

HCIP第五次作业

配置IP地址 r1 [r1]int g0/0/0 [r1-GigabitEthernet0/0/0]ip add 12.0.0.1 24 [r1-GigabitEthernet0/0/0]int lo0 [r1-LoopBack0]ip add 192.168.1.1 24 [r1-LoopBack0]int lo1 [r1-LoopBack1]ip add 10.0.0.1 24 r2 [r2]int g0/0/0 [r2-GigabitEthernet0/0/0]ip add 12.0.0.2 …

在vs里配置c运行环境

勾选环境包 勾选完安装就好 创建c项目 选择相关配置 设置名称和位置 创建c后缀文件 一新建项 二设置名字 输出hello world 代码段 运行结果

C++ 文档加密与解密运用【Crypto++】库

一、下载Cryptopp 鼠标放到下面网址,点击下载即可 github地址(8.7.0版本):https://github.com/weidai11/cryptopp/releases/tag/CRYPTOPP_8_7_0 二 、下载PEM包 pem包官方地址:PEM Pack - Crypto Wiki 三、调用Cry…