Spring IoC详解

server/2024/9/23 22:34:35/

1.Ioc容器的作用

在传统的编程方式中,对象之间的依赖关系往往通过直接调用其他对象的构造函数或方法来建立(即通过new对象的形式),这导致了代码之间的紧密耦合。这就如同一个齿轮组,它拥有多个独立的齿轮,这些齿轮相互啮合在一起,协同工作,共同完成某项任务。在这样的齿轮组中,如果有一个齿轮出了问题,就可能会影响到整个齿轮组的正常运转。增加了维护和扩展的难度。

为了解决对象之间的耦合度过高的问题,软件专家Michael Mattson提出了IOC理论,控制反转(IoC)是一种编程思想,它借助“第三方”容器来实现对具有依赖关系对象之间的解耦。这个“第三方”容器在Spring框架中就是IoC容器。IoC容器负责实例化对象,并管理对象之间的依赖关系,从而实现了依赖关系的反转:应用程序本身不再负责依赖对象的创建和维护,而是将这些任务交给了外部容器。

由于引进了中间位置的“第三方”,也就是IOC容器,使得A、B、C、D这4个对象分离开来,没有了耦合关系,齿轮之间的传动全部依靠“第三方”了,全部对象的控制权全部上缴给“第三方”IOC容器。

2.Ioc深入理解

接下来我们使用商家、外卖平台和点餐人之间的关系作为例子,形象地解释Spring IoC容器如何进行解耦的。

  • 商家:提供食品或服务的实体,例如餐馆。
  • 外卖平台:作为中间方,连接商家和点餐人,负责处理订单、支付等流程。
  • 点餐人:使用外卖平台来点餐的消费者。

 在没有外卖平台的情况下,商家和点餐人需要直接进行交互。商家需要了解哪些点餐人需要他们的服务,而点餐人则需要知道如何联系到商家,并手动处理订单、支付等流程。这种直接的耦合关系使得任何一方在改变时都可能影响到另一方,导致系统难以维护和扩展。

 当引入外卖平台(即Spring IoC容器)后,上述问题得到了有效的解决。外卖平台作为中间层,解耦了商家和点餐人之间的直接交互。商家只需在平台上注册并提供服务,而点餐人则通过平台选择并点餐。这种解耦使得商家和点餐人可以独立地改变和扩展自己的业务,而不需要担心对另一方的影响。

在Spring IoC容器的语境中,商家和点餐人的类(即Bean)不再直接相互依赖,而是通过容器进行连接。容器负责管理Bean的创建、注入和生命周期,实现了它们之间的松耦合。

3.解耦过程详解 

1. 商家入驻(Bean注册)

商家在外卖平台上注册自己的店铺和提供的菜品,这相当于在Spring IoC容器中注册Bean。商家不需要关心哪个点餐人会来点餐,只需要将自己的服务信息提供给外卖平台。

2. 点餐人浏览与选择(依赖声明)

点餐人打开外卖平台,浏览商家的菜品,并选择自己想要点的食物。这个过程在代码中,就相当于点餐人(服务使用者)的类中声明了对商家服务(Bean)的依赖。

3. 外卖平台处理订单(依赖注入)

当点餐人选择好菜品并提交订单时,外卖平台会负责处理这个订单。它会找到对应的商家,通知商家准备食物,并处理支付等事宜。这个过程在Spring IoC容器中,就是通过依赖注入来实现的。容器会检查点餐人的类的依赖声明,找到相应的商家Bean实例,并将其注入到点餐人的类中。

4. 商家制作食物(服务执行)

商家收到外卖平台的通知后,开始制作食物。在Spring IoC的语境中,这相当于商家Bean的实例执行了相应的方法,提供了服务。

5. 外卖平台配送食物(对象管理)

商家制作好食物后,外卖平台会负责配送。这包括安排骑手、跟踪订单状态等。在Spring IoC容器中,这相当于容器负责管理Bean的生命周期,包括它们的创建、销毁以及状态的维护。

6. 点餐人收到食物(服务使用)

最后,点餐人收到了外卖平台送来的食物,完成了整个点餐过程。在代码中,这就相当于点餐人的类使用了注入的商家服务,完成了相应的业务逻辑。

4.示例代码

  • 编写餐品,点餐人,商家,外卖平台类。
  • 商家类提供两个方法,分别是制作食物和获取顾客信息的方法。
  • 外卖平台类提供下单的方法,在方法中调用商家的方法。
java">//餐品
public class Food {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}//点餐人
public class Customer {private String cusName;//顾客姓名//注入顾客姓名public void setCusName(String cusName) {this.cusName = cusName;}public String getCusName() {return cusName;}}//商家-中餐馆
public class ZhongCanGuan {//准备食物public void doFood(Food  food){System.out.println("您有新的订单:请及时处理:顾客点了一份"+food.getName());System.out.println("商家正在准备食物");}//获取顾客信息public void getCustom(Customer customer){System.out.println("顾客姓名:"+customer.getCusName());}
}//外卖平台
public class MeiTuan {//商家入驻private ZhongCanGuan zcg;//顾客入驻private Customer customer;//set方式注入public void setZcg(ZhongCanGuan zcg){this.zcg = zcg;}public void setCustomer(Customer customer){this.customer = customer;}//顾客通过外卖平台下单public void orderFromRestaurant(Food food) {//顾客点餐zcg.doFood(food);//餐馆获取顾客信息zcg.getCustom(customer);System.out.println("外卖平台已安排配送:" + food.getName());}}
  • 编写applicationContext.xml配置文件,管理bean对象
<?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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!--定义餐品--><bean id="food" class="com.kdf.ioc.Food"><!--set方式注入餐品名称--><property name="name" value="宫保鸡丁"/></bean><!--定义商家的bean 商家注册--><bean id="zcg" class="com.kdf.ioc.ZhongCanGuan"/><!--定义点餐人--><bean id="customer" class="com.kdf.ioc.Customer"><!--注入顾客姓名--><property name="cusName" value="张三"/></bean><!--定义外卖平台--><bean id="meiTuan" class="com.kdf.ioc.MeiTuan"><!-- 注入商家Bean --><property name="zcg" ref="zcg" /><!-- 注入点餐人Bean --><property name="customer" ref="customer" /></bean></beans>
  • 编写测试类,模拟点餐
java">import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class DianCanTest {public static void main(String[] args) {// 创建Spring IoC容器实例ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 从容器中获取外卖平台BeanMeiTuan mt = (MeiTuan) context.getBean("meiTuan");//从容器中选择餐品Food  food = (Food) context.getBean("food");//通过外卖平台下单mt.orderFromRestaurant(food);}
}
  • 运行结果如下:


http://www.ppmy.cn/server/2879.html

相关文章

天空盒1-天空盒的实现原理

天空盒是一种常用的实时渲染技术&#xff0c;用于在三维场景中模拟远处环境&#xff0c;例如天空、山脉或城市等。它通过将一个立方体贴图&#xff08;也称为环境贴图&#xff09;投影到场景的背景中&#xff0c;给人一种无限远的感觉。以下是天空盒的实现原理&#xff1a; 创建…

ExpressLRS硬件实测性能分析

ExpressLRS硬件实测性能分析 1. 源由2. 远航测试3. 实验室测试3.1 芯片RSSI与实测功率差异3.2 SNR信噪比稳定3.3 140db衰减器衰减&#xff0c;40个频点信号稳定 4. 外场测试4.1 无屏蔽样品4.2 有屏蔽样品4.3 有屏蔽vs无屏蔽样品 5. 估算6. 总结7. 补充说明 -- 50mW视频 1. 源由…

VUE中如何使用 JavaScript 变量来设置CSS变量,从而修改CSS属性 --color 的值

// Vue 组件&#xff08;组件名称&#xff1a;DataView&#xff09; <template><div :style"{ --mycolor: color }">这是一个带有自定义颜色的元素</div> </template><script setup lang"ts">const props defineProps({ tit…

Zabbix

目录 什么是 Zabbix&#xff1f; 主要组成部分 1. Zabbix Server 2. Zabbix Agent 3. Zabbix Proxy 4. Zabbix Web Interface 5. Zabbix Database Zabbix 的功能特点 1. 多种监控方式 2. 高度可定制性 3. 自动发现和配置 4. 告警和通知 5. 数据可视化和报告 6. 安…

2024年都江堰市农民合作社和家庭农场申报主体条件、入库程序要求

一、项目建设内容 项目建设要结合“天府粮仓”,充分挖掘地种水肥药机各要素,耕种管收各环节的增产潜力为重点,推广应用优良品种、农机农艺融合、集约高效生产等先进技术。 (一)农民合作社 支持示范社改善生产经营条件,应用先进技术,开展农产品质量认证,构建营销体系和建设清…

mysql 查询实战3-解答

对mysql 查询实战3-题目&#xff0c;进行一个解答 11、查询每⽉产品交易与退款情况 目标&#xff1a;查询每⽉产品交易&#xff08;交易总额&#xff0c;交易数&#xff09;与退款情况&#xff08;退款总额&#xff0c;退款数&#xff09; 1&#xff0c;先把日期格式化 使用 E…

【每日算法】理论:深度学习基础 刷题:力扣哈希表回顾

上期文章 【每日算法】理论&#xff1a;AIGC算法相关 刷题&#xff1a;力扣哈希表回顾 文章目录 上期文章一、上期问题二、本期理论问题1、CNN 中的局部连接(Sparse Connectivity)和权值共享(Shared Weights)特点2、GAN 与diffusion的对比3、Stable Diffusion是怎么训练的&…

两个不同的 wxCriticalSectionLocker 的嵌套使用,附代码

两个不同的 wxCriticalSectionLocker 对象&#xff0c;每个都用于锁定不同的临界区&#xff08;wxCriticalSection&#xff09;&#xff0c;是可以嵌套使用的。这意味着&#xff0c;一个线程可以在已经持有一个临界区锁的情况下&#xff0c;获取另一个不同的临界区的锁。 例如…