当前位置: 首页 > news >正文

详解Spring IoCDI(一)

目录

1.什么是IoC

2.IoC应用场景(案例分析) 

2.1传统程序开发

2.2问题分析

2.3解决方案

2.4IoC 优势

3. DI概念

4.IoC详解

4.1Bean的存储

 4.2@Controller(控制器存储)

4.3获取Bean

4.4Bean相关注解


1.什么是IoC

Spring是⼀个开源框架, 他让我们的开发更加简单、Spring 是包含了众多工具⽅法的 IoC 容器 、

IoC(Inversion of Control,控制反转)是Spring的核心思想,在传统的编程模式中,对象的创建和依赖关系的管理通常由程序自身来完成。而在使用了 IoC 思想的框架(如 Spring)中,这些对象的创建以及对象之间依赖关系的建立等控制权由框架来接管,而不是由应用程序代码直接控制

所谓的IOC称之为控制反转,简单来说就是将对象的创建的权力及对象生命周期的管理过程交由Spring框架来处理,从此在开发过程中不在需要关注对象的创建和生命周期的管理,而是在需要的时候由Spring框架提供,这个由Spring框架管理对象创建和生命周期的机制称之为控制反转。

2.IoC应用场景(案例分析) 

2.1传统程序开发

需求:造出一辆能跑的车

先设计轮⼦(Tire) ,然后根据轮⼦的⼤⼩设计底盘(Bottom) ,接着根据底盘设计⻋⾝(Framework) ,最后根据⻋⾝设计好整个汽⻋(Car)

这⾥就出现了⼀个"依赖"关系:汽车依赖车身,车身依赖底盘 ,底盘依赖轮⼦ .

 最终程序的实现代码如下:

public class Car {private Framework framework;public Car() {framework = new Framework();System.out.println("car init...");}public void run() {System.out.println("car run...");}
}public class Framework {private Bottom bottom;public Framework() {bottom = new Bottom();System.out.println("framework init....");}
}public class Bottom {private Tire tire;public Bottom() {tire = new Tire();System.out.println("bottom init...");}
}public class Tire {public Tire() {System.out.println("tire init...size:"+size);}
}

2.2问题分析

这样的设计看起来没问题 ,但是可维护性却很低.接下来需求变更,我们需要加工多种尺寸的轮胎.

那这个时候就要对上⾯的程序进⾏修改了 ,修改后的代码如下所示:

修改之后, 其他调⽤程序也会报错, 们需要继续修改

 

从以上代码可以看出以上程序的问题是: 程序的耦合度⾮常⾼,当最底层代码改动之后 ,整个调用链上的所有代码都需要修改.

2.3解决方案

我们尝试换⼀种思路, 我们先设计汽车的⼤概样子 ,然后根据汽车的样子来设计车身,根据车身来设计 底盘 ,最后根据底盘来设计轮子 . 这时候 ,依赖关系就倒置过来了:轮⼦依赖底盘  底盘依赖车身,车身依赖汽车

此时 ,我们只需要将原来由⾃⼰创建的下级类 ,改为传递的⽅式(也就是注入的⽅式), 因为我们不需要在当前类中创建下级类了 ,所以下级类即使发⽣变化(创建或减少参数), 当前类本⾝也⽆需修改任何代码 ,这样就完成了程序的解耦. 

public class Car {private Framework framework;public Car(Framework framework) {this.framework = framework;System.out.println("car init...");}public void run(){System.out.println("car run...");}
}
public class Framework {private Bottom bottom;public Framework(Bottom bottom) {this.bottom = bottom;System.out.println("framework init....");}
}
public class Bottom {private Tire tire;public Bottom(Tire tire) {this.tire = tire;System.out.println("bottom init....");}
}
public class Tire {private int size;public Tire(int size) {this.size = size;this.color= color;System.out.println("tire init...size:"+size);}
}

代码经过以上调整 ,⽆论底层类如何变化 ,整个调⽤链是不⽤做任何改变的 ,这样就完成了代码之间的解耦 ,从而实现了更加灵活、通⽤的程序设计了。

2.4IoC 优势

在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire

改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car

通⽤程序的实现代码 ,类的创建顺序是反的 ,传统代码是 Car 控制并创建了Framework Framework 创建并创建了 Bottom ,依次往下 ,⽽改进之后的控制权发⽣的反转 ,不是使⽤⽅对象创建并控制依赖对象了是把依赖对象注⼊将当前对象中,依赖对象的控制权不再由当前类控制

这样的话, 即使依赖类发⽣任何改变  前类都是不受影响的 ,这就是典型的控制反转 ,也就是 IoC 实现思想。

IoC 的优点主要包括以下几点:

  1. 降低耦合度:使组件之间的依赖关系更加松散,便于系统的扩展和维护。
  2. 提高代码复用性:组件可以更方便地在不同场景中复用。
  3. 增强灵活性:可以更轻松地替换或修改依赖的对象,而不影响其他部分代码。
  4. 便于测试:可以方便地模拟和替换依赖对象,进行单元测试。
  5. 提升开发效率:开发者无需花费大量时间处理对象创建和依赖管理的繁琐细节。
  6. 更好的架构管理:有助于构建更清晰、合理的系统架构。

3. DI概念

IoC 是一种设计思想,而 DI(Dependency Injection,依赖注入)是实现 IoC 的一种重要方式。

DI 具体指的是将对象之间的依赖关系,通过一定的方式(如构造器注入、Setter 方法注入、字段注入等)在运行时动态地注入到对象中。

可以说 DI 是 IoC 思想在具体技术实现层面的体现,它们紧密相关,共同作用来实现对象创建和依赖管理的解耦与灵活配置。

创建Student类:

public class Student {private String name;public Student(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

创建一个Course类,并通过注解注入Student对象:

@Service
public class Course {@Autowiredprivate Student student;public void showDetails() {System.out.println("依赖注入学生姓名:" + student.getName());}
}

4.IoC详解

通过上⾯的案例, 我们已经知道了Spring IoC DI的基本操作, 接下来我们来系统的学习Spring IoCDI 的操作.前⾯我们提到IoC控制反转 ,就是将对象的控制权交给SpringIOC容器  IOC容器创建及管理对象。也就是bean的存储.

4.1Bean的存储

要把某个对象交给IOC容器管理 ,需要在类上添加⼀个注解:@Component

Spring框架为了更好的服务web应⽤程序, 提供了更丰富的注解.

共有两类注解类型可以实现:

类注解:@Controller@Service@Repository@Component@Configuration.

⽅法注解:@Bean. 

 4.2@Controller(控制器存储)

使用@Controller 存储 bean 的代码如下所示:

 @Controller // 将对象存储到 Spring 中public class UserController {public void sayHi(){System.out.println("hi,UserController...");}}

如何观察这个对象已经存在Spring容器当中了呢? 接下来我们学习如何从Spring容器中获取对象

 @SpringBootApplicationpublic class SpringIocDemoApplication { public static void main(String[] args) { //获取Spring上下⽂对象
ApplicationContext context =  SpringApplication.run(TestSpringTwoApplication.class,args);//从Spring上下⽂中获取对象UserController userController = context.getBean(UserController.class);//使⽤对象userController.sayHello();}
}
}

观察运⾏结果, 发现成功从Spring中获取到Controller对象, 并执⾏ControllersayHello⽅法

如果把@Controller删掉, 再观察运⾏结果

 报错信息显⽰: 找不到类型是: com.example.demo.controller.UserControllerbean

获取bean对象的其他⽅式:

上述代码是根据类型来查找对象, 如果Spring容器中, 同⼀个类型存在多个bean的话, 怎么获取呢

ApplicationContext 也提供了其他获取bean的⽅式, ApplicationContext 获取bean对象的功能, 是父BeanFactory提供的功能.

     // 1. 根据bean名称获取beanObject getBean(String var1) throws BeansException;// 2. 根据bean名称和类型获取bean<T> T getBean(String var1, Class<T> var2) throws BeansException;// 3. 按bean名称和构造函数参数动态创建bean,只适⽤于具有原型(prototype)作⽤域的beanObject getBean(String var1, Object... var2) throws BeansException;// 4. 根据类型获取bean<T> T getBean(Class<T> var1) throws BeansException;// 5. 按bean类型和构造函数参数动态创建bean,只适⽤于具有原型(prototype)作⽤域的bea<T> T getBean(Class<T> var1, Object... var2) throws BeansException;

常⽤的是上述1,2,4, 这三种⽅式,取到的bean是⼀样的,其中1,2种都涉及到根据名称来获取对象. bean的名称是什么呢?

Spring beanSpring框架在运⾏时管理的对象, Spring会给管理的对象起⼀个名字. ⽐如学校管理学⽣ , 会给每个学⽣分配⼀个学号, 根据学号, 就可以找到对应的学⽣ .

Spring也是如此, 给每个对象起⼀个名字, Bean的名称(BeanId)就可以获取到对应的对象.

4.3获取Bean

 @SpringBootApplicationpublic class SpringIocDemoApplication { public static void main(String[] args) { //获取Spring上下⽂对象ApplicationContext context = SpringApplication.run(SpringIocDemoApplication.class,args); //从Spring上下⽂中获取对象//根据bean类型, 从Spring上下⽂中获取对象UserController userController1 = context.getBean(UserController.class); //根据bean名称, 从Spring上下⽂中获取对象UserController userController2 = (UserController) context.getBean("userController"); //根据bean类型+名称, 从Spring上下⽂中获取对象UserController userController3 = context.getBean("userController",UserController.class);System.out.println(userController1);System.out.println(userController2);System.out.println(userController3);

运⾏结果:

地址⼀样, 说明是同一个对象

继承关系和功能⽅⾯来说:

Spring 容器有两个顶级的接⼝ BeanFactory ApplicationContext。

其中 BeanFactory 提供了基础的访问容器的能力,

ApplicationContext 属于 BeanFactory 的⼦类 ,它除了继承了 BeanFactory 的所有功能之外, 它还拥有独特的特性 ,还添加了对国际化⽀持、资源访问⽀持、 以及事件传播等⽅⾯的⽀持

从性能⽅⾯来说:ApplicationContext ⼀次性加载并初始化所有的 Bean 对象 ,⽽ BeanFactory 是需要那个才去加载那个 ,因此更加轻量. (空间换时间)

4.4Bean相关注解

在 Spring 中,有一些与 Bean 相关的重要注解,比如:

@Component:这是一个通用的组件注解,用于将类标识为可被 Spring 容器管理的 Bean。

@Service:通常用于标识服务层的 Bean,业务逻辑层, 处理具体的业务逻辑.

@Repository:一般用于标识数据访问层(如数据库操作相关)的 Bean。

@Controller:控制层, 接收请求, 对请求进⾏处理, 并进⾏响应.

@Configuration :配置层. 处理项⽬中的⼀些配置信.

此外,还有@AutoWired用于自动注入依赖等注解,它们共同协作来实现对 Bean 的管理和配置

程序员看到类注解之后 ,就能直接了解当前类的用途.

相关文章:

详解Spring IoCDI(一)

目录 1.什么是IoC 2.IoC应用场景&#xff08;案例分析&#xff09; 2.1传统程序开发 2.2问题分析 2.3解决方案 2.4IoC 优势 3. DI概念 4.IoC详解 4.1Bean的存储 4.2Controller&#xff08;控制器存储&#xff09; 4.3获取Bean 4.4Bean相关注解 1.什么是IoC Spring…...

Android 14 - 绘制体系 - 概览

从Android 12开始&#xff0c;Android的绘制系统有结构性变化&#xff0c; 在绘制的生产消费者模式中&#xff0c;新增BLASTBufferQueue&#xff0c;客户端进程自行进行queue的生产和消费&#xff0c;随后通过Transation提交到SurfaceFlinger&#xff0c;如此可以使得各进程将缓…...

【RAG论文】文档树:如何提升长上下文、非连续文档、跨文档主题时的检索效果

RAPTOR Recursive Abstractive Processing for Tree-Organized RetrievalICLR 2024 Stanfordhttps://arxiv.org/pdf/2401.18059 RAPTOR&#xff08;Recursive Abstractive Processing for Tree-Organized Retrieval&#xff09;是一种创建新的检索增强型语言模型&#xff0c;它…...

【前端每日基础】day27——小程序开发

小程序开发详细介绍 基本概念 小程序&#xff1a;小程序是一种无需下载安装即可使用的应用。用户通过微信搜索或扫描二维码即可打开小程序。小程序具有触手可及、用完即走、体验良好的特点。 组成部分&#xff1a; WXML&#xff1a;用于描述页面的结构。 WXSS&#xff1a;用于…...

【C语言】指针速览

指针速览 指针1.野指针与空指针2. 空类型指针 void *3. 指针常量4. 常量指针5. 指向常量的指针常量6. 指针操作数组6.1 数组名作为函数参数 7. 多级指针8. 函数指针8.1 函数指针数组 最后 指针 指针就是内存的字节单元编号地址&#xff0c;指针变量就是存放地址的变量。 1.野…...

Java基础学习:深入解析Java中的位运算符

在Java中&#xff0c;位运算符用于对整数类型的值进行位运算。以下是Java中的位运算符&#xff1a; 位与(&)&#xff1a;两位都为1时&#xff0c;结果为1&#xff0c;否则为0。 位或(|)&#xff1a;两位中有1个为1&#xff0c;结果为1。 位非(~)&#xff1a;位的反&#…...

9.Redis之list类型

list相当于链表、数据表 1.list类型基本介绍 列表中的元素是有序的"有序"的含义,要根据上下文区分~~有的时候,谈到有序,指的是"升序","降序”有的时候,谈到的有序,指的是, 顺序很关键~~如果把元素位置颠倒,顺序调换.此时得到的新的 List 和之前的 Li…...

Git 的安装和使用

一、Git 的下载和安装 目录 一、Git 的下载和安装 1. git 的下载 2. 安装 二、Git 的基本使用-操作本地仓库 1 初始化仓库 1&#xff09;创建一个空目录 2&#xff09;git init 2 把文件添加到版本库 1&#xff09;创建文件 2&#xff09;git add . 3&#xff09;g…...

大模型时代的具身智能系列专题(五)

stanford宋舒然团队 宋舒然是斯坦福大学的助理教授。在此之前&#xff0c;他曾是哥伦比亚大学的助理教授&#xff0c;是Columbia Artificial Intelligence and Robotics Lab的负责人。他的研究聚焦于计算机视觉和机器人技术。本科毕业于香港科技大学。 主题相关作品 diffusio…...

基于springboot+vue的社区医院管理服务系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…...

车载电子电器架构 —— 智能座舱标准化意义

车载电子电器架构 —— 智能座舱标准化意义 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消…...

Compose在xml中使用滑动冲突处理

一、背景 在现有Android项目中使用Compose可能存在滑动冲突问题&#xff0c;例如 SmartRefreshLayoutCoordinatorLayoutComposeView(ComposeView这里又是一个LazyColumn) 二、解决方案 官方介绍&#xff1a;https://developer.android.google.cn/develop/ui/compose/touch-inp…...

微信网页版登录插件v1.1.1

说到如今的微信客户端&#xff0c;大家肯定会有很多提不完的意见或者建议。比如这几年体积越来越大&#xff0c;如果使用频率比较高&#xff0c;那占用空间就更离谱了。系统迷见过很多人电脑C盘空间爆满&#xff0c;都是由于微信PC版造成的。 而且&#xff0c;它还加了很多乱七…...

华为实训课笔记 2024

华为实训 5/205/215/225/235/275/28 5/20 5/21 5/22 5/23 5/27 5/28...

HTML静态网页成品作业(HTML+CSS)——宠物狗介绍网页(3个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有3个页面。 二、作品演示 三、代…...

网络模型-路由策略

一、路由策略 路由策略(Routing Policy)作用于路由&#xff0c;主要实现了路由过滤和路由属性设置等功能&#xff0c;它通过改变路由属性(包括可达性)来改变网络流量所经过的路径。目的:设备在发布、接收和引入路由信息时&#xff0c;根据实际组网需要实施一些策略&#xff0c…...

【MySQL精通之路】InnoDB(7)-锁和事务模型

1.InnoDB锁 【MySQL精通之路】InnoDB(7)-锁和事务模型(1)-锁-CSDN博客 2.InnoDB事务模型 【MySQL精通之路】InnoDB(7)-锁和事务模型(2)-事务模型-CSDN博客 3.InnoDB中不同SQL语句设置的锁 4.幻影行 5.InnoDB中的死锁 5.1InnoDB死锁示例 5.2死锁检测 …...

深度学习创新点不大但有效果,可以发论文吗?

深度学习中创新点比较小&#xff0c;但有效果&#xff0c;可以发论文吗&#xff1f;当然可以发&#xff0c;但如果想让编辑和审稿人眼前一亮&#xff0c;投中更高区位的论文&#xff0c;写作永远都是重要的。 那么怎样“讲故事”才能让论文更有吸引力&#xff1f;我总结了三点…...

【ARM Cache 系列文章 7.1 – ARMv8/v9 MMU 页表配置详细介绍 02 】

文章目录 Translation table descriptorTable descriptor format页面粒度和地址长度粒度(Granules)48位和52位地址TCR_ELx.DSVTCR_EL2.DSFEAT_LPA块描述符|页描述符紧接上篇文章【ARM Cache 系列文章 7 – ARMv8/v9 MMU 页表配置 01 】 Translation table descriptor</...

Mysql搭建主从同步,docker方式(一主一从)

服务器&#xff1a;两台Centos9 用Docker搭建主从 使用Docker拉取MySQL镜像 确保两台服务器都安装好了docker 安装docker请查看&#xff1a;Centos安装docker 1.两台服务器都先拉取mysql镜像 docker pull mysql 2.我这里是在 /opt/docker/mysql 下创建mysql的文件夹用来存…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...