Spring ( 三 ) SpringIoC

news2025/2/28 17:28:22

3.SpringIoC

Spring 核心 是 通过IoC 降低 项目中的类之间的耦合

IoC Inversion of Control 控制反转:
应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。

​ 这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转。

DI Dependency Injection依赖注入:
在运行期,由外部容器动态的将依赖对象注入到组件内部中。

在这里插入图片描述

主要分成两个步骤:

​ 先将 类 注册到 SpringIoC 容器上, 也就由SpringIoC容器来管理Bean

​ 再根据 业务需求, 通过SpringIoC容器来搭建类对象之间的关系 , 也就是 依赖注入

3.0.准备

3.0.1.Maven导入依赖

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.3.6</version>
    </dependency>

由于 Maven 可以自动关联依赖, 依赖结构图

在这里插入图片描述

3.0.2.添加配置文件

在 maven项目的 resources 文件夹中添加 Spring配置文件

右键菜单选择 New > XML Configuration File > Spring config

在这里插入图片描述

填写文件名 spring-config

在这里插入图片描述

打开文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>

3.1.配置文件方式

3.1.1.声明Bean

在 配置文件中 增加<bean>结点, 用于 将类 注册到SpringIoC容器中

id 是 注册到SpringIoC容器时的别名

class 是 类的实际路径

    <bean id="hw" class="com.yuan.spring.beans.HouWang"  ></bean>

	<bean id="hhr" class="com.yuan.spring.beans.HongHair"></bean>
    <bean id="tsgz" class="com.yuan.spring.beans.TieShanGongZhu"></bean>
    <bean id="nmw" class="com.yuan.spring.beans.NiuMoWang"></bean>

3.1.2.IoC容器

Spring框架的IoC容器(Inversion of Control控制反转容器),是Spring框架的核心组件之一,其作用是管理Spring应用程序中的Java对象,也可称为Bean容器

容器负责在应用程序启动时实例化所有的Bean,并负责将它们注入到其他Bean中,从而实现依赖注入(DI)。

简单来说,Spring IoC容器就是一个集中管理和维护Java对象的容器,可以通过IoC容器将对象的创建和管理过程转移到Spring容器中进行,以达到解耦的目的。

Spring IoC容器主要有两种实现方式:BeanFactoryApplicationContext

BeanFactory是最基本的IoC容器,它只提供了对象的实例化和依赖注入等最基本的功能。而ApplicationContext则是在BeanFactory的基础上做了更多的扩展,提供了更多的企业级特性,例如AOP、国际化和事件传播等功能。

Spring IoC容器使用XML配置文件或注解来描述Bean之间的依赖关系和属性值的设定,并且可以通过配置文件或代码设置不同的Bean作用域(如 Singleton、Prototype等)以及生命周期的管理。

容器在启动时会读取这些配置信息,并根据配置信息实例化Bean并维护它们的依赖关系,当某个Bean被需要时,容器会根据配置信息将对应的Bean返回给调用方。

在这里插入图片描述

3.1.2.1.根据 编译路径下的 配置文件 生成 IoC 容器

// ClassPath 编译路径   Xml 文件格式  
AbstractApplicationContext beanFactory = new ClassPathXmlApplicationContext("spring-config.xml");

3.1.2.2.根据 文件物理路径下的 配置文件 生成IoC 容器

// FileSystem 文件系统 Xml 文件格式
AbstractApplicationContext beanFactoryFile = new FileSystemXmlApplicationContext("D:\\spring-config.xml");

3.1.3.得到实例

从SpringIoC 中得到 类的实例对象

// 根据配置文件中 注册的id 得到 类的实例对象实例
// 这种方式返回Object类型 要强制转形
HouWang hw = (HouWang) beanFactory.getBean("hw");

// 根据配置文件中 注册的class类型 得到 类的实例对象实例
HouWang houWang = beanFactory.getBean(HouWang.class);

3.1.4.作用域

Spring IoC 容器中的对象都有作用域(Scope)指定了 Bean 实例的创建和生命周期管理方式。

3.1.4.1.分类

Spring 框架支持如下常见的作用域:

  1. Singleton:单例模式,一个 Bean 实例在整个应用中只创建一次,所有的请求都共享同一 Bean 实例。这是默认的作用域。

    ​ 当SpringIoC容器创建时, 就创建了Bean的实例

  2. Prototype:原型模式,每次请求都会创建一个新的 Bean 实例。即每个 Bean 引用都会创建一个新的实例。

  3. Request:每个 HTTP 请求(即每次 HTTP 请求)都会创建一个新的 Bean 实例,适用于 Web 应用开发。

  4. Session:每个用户会话(即用户登陆时创建的会话)都会创建一个新的 Bean 实例。

  5. GlobalSession:实例具有全局作用域,适用于 Portlet 应用开发,使用时需要在 Web.xml 中打开 Portlet 的支持。

    ​ 在新的版本中基本不再支持

  6. Application : bean被定义为在ServletContext的生命周期中复用一个单例对象。

  7. websocket:bean被定义为在websocket的生命周期中复用一个单例对象。

其中 单例模式与原型模式是在普通项目环境下就可以使用

但在Web环境下增加下面的监听器, 开启其它的作用域

<listener>
      <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

3.1.4.2.单例模式

在 Spring 中,可以在 Bean 的定义中使用 scope 属性来指定作用域。

默认是Singleton单例模式.

启动测试代码:

		// 得到 SpringIoC 容器
		AbstractApplicationContext beanFactory = new ClassPathXmlApplicationContext("spring-config.xml");
		// 得到 id 是 hw 的第一个实例
		HouWang swk = (HouWang) beanFactory.getBean("hw");
		// 得到 id 是 hw 的第二个实例
		HouWang sds = (HouWang) beanFactory.getBean("hw");
		// 通过 == 判断 两个 实例的引用是否为同一个
		System.out.println(swk==sds);
		// 关闭容器
		beanFactory.close();
		// 再次 获取实例
		HouWang dzsf = (HouWang) beanFactory.getBean("hw");
		System.out.println("dzsf = " + dzsf);

得到结果

石破天惊
true
Exception in thread "main" java.lang.IllegalStateException: BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext

只打印了一次 “石破天惊” 说明 构造方法只被调用一次, 也就是只实例化一次

打印 true 表明, 两个引用是同一个实例

后面的报错说明 , 当关闭SpringIoC容器后, 就不能再得到实例了, 也就是Bean的实例只在SpringIoC容器的生命周期之内

3.1.4.3.原型模式

修改Spring的配置文件, 通过 scope属性 调整 hw的作用域为 prototype 原型模式

 <bean id="hw" class="com.yuan.spring.beans.HouWang" scope="prototype"   ></bean>

再次测试上面的代码 , 得到的结果

石破天惊
石破天惊
false

打印了两次 “石破天惊” , 说明 实例化两次, 说明在每一次getBean()时都实例化新的对象

所以通过 “==” 判断返回 false

3.1.5.依赖注入

Spring 依赖注入(Dependency Injection)是 Spring 框架的核心特性之一。它允许我们从外部配置文件或注解中将对象的依赖关系注入到对象中,以达到松散耦合和易于维护的目的。

所谓依赖注入, 本质来是为应用对象的私有属性赋值

Spring 依赖注入主要有以下几种类型:

  1. 构造函数注入(Constructor injection):通过构造函数将依赖项传递给 Spring 容器创建的对象,通常适用于必须注入的依赖项。

  2. Setter 方法注入(Setter injection):通过 set 方法将依赖项传递给对象,通常适用于可选依赖项。

  3. 字段注入(Field injection):通过对象的字段(即属性)将依赖项注入到对象中。通常在属性上使用注解

  4. 接口注入(Interface injection):通过实现接口向对象注入依赖项,通常使用 ApplicationContextAware 接口实现。

以上注入方式的选择取决于应用程序的需求和使用环境。例如,如果我们需要在对象创建时立即注入一些必需依赖项,则最好使用构造函数注入;如果我们需要在运行时注入可选依赖项,则最好使用 Setter 方法注入。

3.1.5.1.构造函数注入

修改配置文件, 利用有参构造器为mingZi属性赋值

<constructor-arg> : 配置有参构造注入

index : 参数的序号

value : 为参数赋的值

    <bean id="hw" class="com.yuan.spring.beans.HouWang" >
        <constructor-arg index="0" value="齐天大圣"></constructor-arg>
    </bean>

测试, 调用 打招呼方法

		// 得到 SpringIoC 容器
		AbstractApplicationContext beanFactory = new ClassPathXmlApplicationContext("spring-config.xml");
		// 得到 id 是 hw 的第一个实例
		HouWang swk = (HouWang) beanFactory.getBean("hw");
		// 调用打招呼方法
		swk.daZhaoHu();

得到结果可以看到, 调用了有参构造器, 并为 mingZi 赋值

我齐天大圣来了
大家好,我是齐天大圣

3.1.5.2.Setter 方法注入

再次修改 配置文件

<property> : 配置Setter 方法注入

name : 与 Setter方法名配置 , 如 : 类中有 setMingZi(String mingZi) , setYg(IYaoGuai yg) 等方法

value : 赋简单值

ref : 赋 对象 值, 如 : nmw 对应 的 <bean id="nmw">

    <bean id="hw" class="com.yuan.spring.beans.HouWang"  >
        <property name="mingZi" value="齐天大圣"></property>
        <property name="yg" ref="nmw"></property>
    </bean>
    
    <bean id="hhr" class="com.yuan.spring.beans.HongHair"></bean>
    <bean id="tsgz" class="com.yuan.spring.beans.TieShanGongZhu"></bean>
    <bean id="nmw" class="com.yuan.spring.beans.NiuMoWang"></bean>

测试, 调用 打招呼, 打妖怪 方法

		// 得到 SpringIoC 容器
		AbstractApplicationContext beanFactory = new ClassPathXmlApplicationContext("spring-config.xml");
		// 得到 id 是 hw 的第一个实例
		HouWang swk = (HouWang) beanFactory.getBean("hw");
		// 调用打招呼方法
		swk.daZhaoHu();
		// 调用 打妖怪方法
		swk.daYaoGuai();

得到结果可以看到, 打妖怪 依赖的是 NiuMoWang 牛魔王 类 , 可以修改配置文件 再测试

石破天惊
大家好,我是齐天大圣
啊!我牛魔王会回来的!

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

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

相关文章

【Linux从入门到精通】一文带你理解进程概念

我们通过对上篇文章冯诺依曼体系结构对硬件进行讲解后&#xff0c; 本篇文章会对进程进行深入讲解。同时会讲解PCB&#xff08;进程控制块&#xff09;。希望本篇文章内容会对你有所帮助。 文章目录 一、再次理解操作系统 1、1 操作系统的作用 1、2 操作系统的管理 二、进程基本…

基于Kubernetes集群构建大中型企业CICD应用平台(5)--Integrate工具

5.1、jenkins介绍 持续集成、持续部署的工具很多&#xff0c;其中Jenkins是一个开源的持续集成平台。 Jenkins涉及到将编写完毕的代码发布到测试环境和生产环境的任务&#xff0c;并且还涉及到了构建项目等任务。 Jenkins需要大量的插件保证工作&#xff0c;安装成本较高&am…

Java Web开发:Spring Boot和Spring Cloud的应用和实践

一、介绍 Java Web开发是当今互联网时代中的一项重要技术&#xff0c;随着互联网的发展和应用场景的不断扩大&#xff0c;Java Web开发技术也得到了广泛的应用。而Spring Boot和Spring Cloud作为Java Web开发中最常用的技术之一&#xff0c;已经成为了很多开发者必备的技能。本…

使用Vue3和Typescript实现可复用的路由标签页和面包屑导航组件

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: 三十天精通 Vue 3 文章目录 一、为什么需要可复用的路由标签页和面包屑导航组件1.1 前端应用导航的问题1.2 解决问题的方法二、Vue3和Typescript基础知识回…

shell脚本中数组的运用以及排序算法

shell脚本中数组的运用 一、数组的介绍1、概念2、定义方法3、数组包括的数据类型 二、关于数组的操作1、获取数组长度2、获取数组各个元素的下标3、获取数组列表或单个元素4、对数组切片输出5、对数组里的元素替换6、删除单个元素或数组7、数组追加元素8、向函数传入数组的值 三…

Learning C++ No.20 【红黑树实战】

引言&#xff1a; 北京时间&#xff1a;2023/5/12/20:30&#xff0c;今天周五&#xff0c;周五不摆烂从我做起&#xff0c;虽然刚睡醒&#xff0c;但是今天如果论学习时长&#xff0c;那可能是许久以来最长的一天&#xff0c;从早上6:40晨跑回来坐在凳子上&#xff0c;一坐久坐…

在 I/O 看未来 | 开发者集合!官方学习资源已更新,即 课 解锁新技能!

看完 Google I/O 2023 的精彩内容 你是否已跃跃欲试&#xff0c;准备充电学习&#xff1f; 马上跟随 Google 开发者在线课程 刷新知识储备和开发技能 将技术热爱落地为实践应用&#xff01; "解码 Google I/O 洞见科技未来" 征文活动 也向身为技术爱好者的你发出召唤…

【Wi-Fi】802.11/802.11b/802.11g/802.11n/802.11a/802.11ac/802.11ax/802.11be

WiFi发展历史 IEEE 802.11 Protocol Release Date Frequency Band Bandwidth Max Throughput 802.11-1997 1997 2.4GHz 22MHz 2Mbps 802.11b 1999 2.4GHz 22MHz 11Mbps 802.11a 1999 5GHz 20MHz 54Mbps 802.11g 2003 2.4GHz 20MHz 54Mbps 802.11n (W…

Kubernetes❀实战入门

Kubernetes❀实战入门 4. 实战入门4.1 Namespace4.1.1 **查看**4.1.2 **创建**4.1.3 **删除**4.1.4 **配置方式** 4.2 Pod4.2.1 创建并运行4.2.2 查看pod信息4.2.3 访问Pod4.2.4 删除指定Pod4.2.5 配置操作 4.3 Label4.3.1 命令方式4.3.2 配置方式 4.4 Deployment4.4.1待操作。…

第二章 介绍Productions - 互操作性制作简介

文章目录 第二章 介绍Productions - 互操作性制作简介介绍Productions设置Production的消息流 第二章 介绍Productions - 互操作性制作简介 互操作性产品的目的是使能够连接系统&#xff0c;以便可以在它们之间转换和路由消息。要连接系统&#xff0c;需要开发、配置、部署和管…

( 位运算 ) 693. 交替位二进制数 ——【Leetcode每日一题】

❓693. 交替位二进制数 难度&#xff1a;简单 给定一个正整数&#xff0c;检查它的二进制表示是否总是 0、1 交替出现&#xff1a;换句话说&#xff0c;就是二进制表示中相邻两位的数字永不相同。 示例 1&#xff1a; 输入&#xff1a;n 5 输出&#xff1a;true 解释&#…

【FreeRTOS】——API函数任务创建与删除挂起与恢复

目录 前言&#xff1a; 一、任务创建与删除的API函数 二、任务挂起与恢复的API函数 总结&#xff1a; 前言&#xff1a; 博客笔记根据正点原子视频教程编辑&#xff0c;仅供学习交流使用&#xff01; 一、任务创建与删除的API函数 任务的创建和删除的本质就是调用FreeRT…

小宁ChatGPT智能机器人上线,无需魔法注册即可使用!

​大家好&#xff0c;今天我要向大家介绍一款基于人工智能技术的聊天机器人——ChatGPT。ChatGPT可以与用户进行自然语言交互&#xff0c;回答用户的问题、提供服务、进行闲聊等&#xff0c;让聊天变得更有趣。 小宁ChatGPT是对接ChatGPT官方api&#xff0c;实现无需魔法无误差…

使用Visual Studio 2019 创建JNI式的动态库及在Java代码中的使用

文章目录 JNI简介JNI 数据类型与 Java 、C 类型对比JNI式动态库函数编码规则Visual Studio下的编码JNI式动态库在Java代码中的使用改进版通过javah命令自动生成.h文件 JNI简介 JNI (Java Native Interface) 是 Java 沟通 Native 语言&#xff08;主要是C、C&#xff09;的桥梁…

《花雕学AI》34:用13种Prompt玩转AI聊天机器人—揭秘ChatGPT模型

引言&#xff1a; 聊天机器人是一种能够通过自然语言进行交流的智能系统&#xff0c;它可以模仿人类的对话方式&#xff0c;提供各种信息、服务或娱乐。随着人工智能技术的发展&#xff0c;聊天机器人的应用越来越广泛&#xff0c;从电商、教育、医疗、旅游等领域&#xff0c;到…

Spring ( 四 ) 注解注入

3.2.注解方式 目前 主流的方式 是使用注解方式来实现IoC效果. 3.2.1.配置类 在 config包下增加 SpringConfig 配置类 Configuration 声明当前类为配置类, SpringIoC容器会根据配置类信息进行配置 ComponentScan() bean扫描路径 , SpringIoC容器只维护 声明的路径下的增加&q…

华为OD机试真题 Java 实现【最多提取子串数目】【2023Q1 100分】

一、题目描述 给定由[a-z] 26 个英文小写字母组成的字符串 A和 B&#xff0c;其中A中可能存在重复字母&#xff0c;B 中不会存在重复字母&#xff0c;现从字符串 A 中按规则挑选一些字母&#xff0c;可以组成字符串 B。 挑选规则如下: 同一个位置的字母只能被挑选一次&#…

Qt连接Sqlite3并使用Qtableview实时显示数据,重写QSqlQueryModel实现文本居中

文章目录 前言一、引入SQL模块二、数据库的基本操作三、示例完整代码四、下载链接总结 前言 什么是 SQLite&#xff1f; SQLite是一个进程内的库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库&#xff0c;这意味着与其…

软件 工程

目录 第十章、软件工程1、瀑布模型&#xff08;SDLC&#xff09;2、快速原型模型3、增量模型4、螺旋模型5、Ⅴ模型6、喷泉模型7、构建组装模型&#xff08;CBSD&#xff09;8、统一过程&#xff08;RUP&#xff09;9、敏捷开发方法10、信息系统开发方法11、需求开发12、结构化设…

Codeforces Round 872 (Div. 2) 题解

总结&#xff1a;5.9有同学问B题&#xff0c;所以就连同ABC题一起做了&#xff0c;都算是思维题吧&#xff0c;难度不算高 A. LuoTianyi and the Palindrome String 思路&#xff1a;输入的都为回文字符串&#xff0c;如果输入的回文字符串每个字符都相同&#xff0c;如"…