Spring 学习笔记(3)控制反转 IoC
本篇文章主要对 Spring 框架中的核心功能之一控制反转 (IOC,Inversion of Control)进行介绍,采用理论 + 实战的方式给大家阐述其中的原理以及明确需要注意的地方。
控制反转
通俗的讲,控制反转是一种思想,也是工程设计的一种原则,通过控制反转可以将对象的一部分控制权转移到容器(例如 Spring 容器)中,由容器帮我们控制创建对象,我们只需要在上下文中进行配置即可,配置的过程其实就是创建对象的过程。
其思想是:反转资源获取的方向。传统的资源查找的方向是要求组件向容器发起请求查找资源,同时容器返回资源。而采用 IoC 之后,容器会主动的将资源推送给它所管理的组件,组件所要做的就是选择一种合适的方式来接收资源。
而 DI(Denpendency Injection)是 IoC 的另一种表述方式,即组件以一些预先定义好的方式(例如 setter 方法)接收来自容器的资源注入。
此外还可以用构造函数的方式注入
这种实现方式有什么好处呢?
首先,在传统的程序设计中,我们想要使用某个对象就需要 new 一个对象,创建对象的实例,这是我们主动创建的过程,而引入 IoC 之后,我们将这个创建对象的过程交给容器去做,由容器去控制对象的创建,当然也可以注入依赖对象,而这个过程是对象被动的接受依赖对象的。这里的容器就是我们正在学习的 Spring,它可以创建对象的实例,当我们需要对象时,直接在 Spring 容器中获得即可,直接去拿就好了。
如何拿到呢?
这时就需要用到上下文配置文件了,也就是我们常说的.xml配置文件,我们只需要在配置文件中将指定的实现类的路径名(全限定名)配置到 xml 文件中即可。
你看,通过这种方式可以很好的将创建对象的过程与我们主业务进行很好的分离,更好的降低耦合度,因为我们让 IoC 容器帮助我们去找对象并将相应的依赖注入到对象中,这时我们就不需要再主动去创建对象了。简单点说,就是以后需要写 new 的地方,我们都可以交给 IoC 容器去做,在这里也就是让 Spring 去做就可以了。
当然,这个地方配合依赖注入(DI,Dependency Injection) 来讲可能会好一点,不过没关系,博主将通过一个简单的小例子来让你明白控制反转的具体操作时什么样子的。
IoC 简单案例
在进行编码之前,我们需要一些准备工作,如环境配置说明、导入相应 jar 包、创建目标类等等,下面我们一步一步来做。
1.1 环境说明
以下声明了所有使用的编码环境,已经确定能够在该环境下进行所有的编码测试等,关于 jar 包,我们用到的时候在说。
- JDK:11
- 软件:IDEA 2021.2.1
- 操作系统:Windows 10
1.2 导入相应 jar 包
这里的 jar 暂时用到的是 4+1,即 4 个核心(core、beans、beans、expression)和 1 个依赖(commons.logging),这些包你可以在官网下载。如下所示:
- spring-core-3.2.0.RELEASE.jar
- spring-beans-3.2.0.RELEASE.jar
- spring-beans-3.2.0.RELEASE.jar
- spring-expression-3.2.0.RELEASE.jar
- com.springsource.org.apache.commons.logging-1.1.1.jar
1.3 利用 Maven 快速配置 Spring 开发环境
详细方法:Click Here
1.4 编写目标接口与实现类
我们在这里创建一个 UserService 接口,然后再创建它的一个实现类 UserServiceImpl,类里面由一个添加用户的方法 save(),然后方法里面输出一条语句即可。如下所示:
// UserService.java
public interface UserService {
public void save();
}
// UserServiceImpl.java
public class UserServiceimpl implements UserService {
public void save() {
System.out.println("ioc...save");
}
}
1.5 编写测试类
然后我们再写一个测试类,用于对目标类进行测试,如下所示:
// SpringTest.java
public class SpringTest {
@Test
public void test1() {
// 之前开发时使用的方式: new
UserService userService = new UserServiceimpl();
userService.save();
}
}
这时运行测试类就得到了输出语句。你可以看到,在测试类中,我们使用以前的方法 new 了一个对象,然后调用了 addUser() 方法,最后将输出语句打印。这显然不是我们目的,我们要实现的是用 Spring 进行 IoC 后,得到同样的效果。
1.6 编写配置文件
下面就开始创建一个配置文件,我们暂且将其命名为 bean.xml(开发中一般将其命名为 applicationContext.xml)。配置文件一般放置于 src 目录下,如下所示:
<!-- bean.xml -->
<?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">
<!-- 配置service-->
<bean id="userServiceId" class="com.my.a_ioc.UserServiceImpl"></bean>
</beans>
在 <beans> 标签中的像网址一样的链接表示 schema 约束(模式约束),由于我们要使用到 <bean> 标签,该标签可以帮助我们配置需要创建的对象,所以这里应该将其添加进来。接下来你可以看到在 <bean> 标签中有两个属性,其中 id 是用于从 Spring 容器中获得实例的,class 表示创建实例的全限定名,即包名+类名。
bean.xml 配置文件写好以后,我们需要再编写一个测试类去测试它,这个测试类将演示如何从 Spring 容器中获取实例,如下所示:
@Test
public void Test2() {
//1、获得容器
String xmlPath = "src/main/resources/bean.xml";
// File Not Find?
//ApplicationContext app = new ClassPathXmlApplicationContext(xmlPath);
ApplicationContext app = new ClassPathXmlApplicationContext("bean.xml");
//2、获得内容,不需要自己new,直接从spring容器中获取: getBean 方法
UserService userService = (UserService) app.getBean("userService");
userService.save();
}
首先要指定bean.xml文件的路径,这里可以右击配置文件,选择Copy Qualified Name即可,然后将com之前的部分删掉。这里通过ClassPathXmlApplicationContext加载bean.xml文件,返回一个ApplicationContext对象,此过程实例化一个 IoC 容器。
然后通过getBean方法获取配置的bean,参数userServiceId与之前在bean.xml文件中的id是相同的。由于其返回的类型是Object,所以在这里我们将其强转成UserService类型的,最后调用addUser()方法即可。输出结果与之前实现的方法相同。
2.总结
至此,一个简单的 IoC 示例就完成了。让我们再梳理一下 IoC 容器是如何工作的。
首先是配置文件的准备,在配置文件中声明bean,为bean配置元数据,例如:id、class,然后 IoC 容器会对配置文件中的元数据进行解析,得到元数据后进行实例化、配置及组装bean操作,最后在测试类中实例化容器,获取需要的bean。主要的过程是对bean的定义以及元数据的配置。
如果你认为文章有错误或者描述不准确的话,请与我联系,谢谢!。另外,你还可以参考下面的链接进一步加深对 IoC 的理解。
参考
Spring 学习笔记(3)控制反转 IoC的更多相关文章
- Spring学习笔记——01 控制反转
想一下之前学的Java,如果某个类需要引用某个对象,则需要手动new一个出来.这样带来的一个问题就是,若被引用的类发生改动或被删除,则引用它的所有类都会报错.因为两个类耦合在一起了.解决的办法就是不由 ...
- Spring.NET学习笔记1——控制反转(基础篇)
在学习Spring.NET这个控制反转(IoC)和面向切面(AOP)的容器框架之前,我们先来看一下什么是控制反转(IoC). 控制反转(Inversion of Control,英文缩写为IoC),也 ...
- Spring学习笔记(4)——IoC学习
IoC理论的背景我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 图1:软件系统中耦合的对象 如果我们打开机械式手表 ...
- Spring学习笔记(5)——IoC再度学习
学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...
- spring学习总结一----控制反转与依赖注入
spring作为java EE中使用最为广泛的框架,它的设计体现了很多设计模式中经典的原则和思想,所以,该框架的各种实现方法非常值得我们去研究,下面先对spring中最为重要的思想之一----控制反转 ...
- Spring学习笔记之基础、IOC、DI(1)
0.0 Spring基本特性 Spring是一个开源框架:是基于Core来架构多层JavaEE系统 1.0 IOC 控制反转:把对象的创建过程交给spring容器来做. 1.1 application ...
- Spring基础(一)_控制反转(IOC)
Spring-IOC 1.简述 1.1 依赖注入DI 现实开发中,每一个应用都会由两个或多个类组成,这些类之间相互协作完成特定的业务逻辑.根据传统做法,每个对象负责管理与自己协作的对象的引用(也就是, ...
- Spring 学习笔记(二)—— IOC 容器(BeanFactory)
使用Spring IoC容器后,容器会自动对被管理对象进行初始化并完成对象之间的依赖关系的维护,在被管理对象中无须调用Spring的API. 为了实现IoC功能,Spring提供了两个访问接口: or ...
- Spring学习笔记(6)——IoC的三种注入方式
1.接口注入(不推荐) 2.构造器注入(死的应用) 3.getter,setter方式注入(比较常用) Type1 接口注入 我们常常借助接口来将调用者与实现者分离.如: public class C ...
- 一、Spring的控制反转(IOC)学习
一.控制反转 1.什么是控制反转? 控制反转(Inversion of Control,缩写为IoC),是面向对象中的一种设计原则,可以用来减低计算机代码之间的耦合度.其中最常见的方式叫做依赖注入(D ...
随机推荐
- 【源码系列#02】Vue3响应式原理(Effect)
专栏分享:vue2源码专栏,vue3源码专栏,vue router源码专栏,玩具项目专栏,硬核推荐 欢迎各位ITer关注点赞收藏 Vue3中响应数据核心是 reactive , reactive 的实 ...
- python数据类型元组、列表、集合、字典相互嵌套
系统 Windows 10 专业工作站版22H2 软件 python-3.9.6-amd64.exe 拓展库: jupyter==1.0.0 notebook==7.0.6 1.元组嵌套 1.1 元组 ...
- [ARC145D] Non Arithmetic Progression Set
Problem Statement Construct a set $S$ of integers satisfying all of the conditions below. It can be ...
- [ABC274D] Robot Arms 2
Problem Statement You are given a sequence $A = (A_1, A_2, \dots, A_N)$ of length $N$ consisting of ...
- Vue绑定Style和Class写法
vue2写法 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
- SpringBoot内容协商机制
1.是什么? SpringBoot内容协商机制是一种实现了内容协商(Content Negotiation)的Web服务器,它可以根据客户端请求的不同,将响应返回给客户端. 在传统的Web服务器中,如 ...
- LeetCode227:基本计算器|| (栈、模拟)
解题思路:两个双端队列模拟,一个存放操作数 a,另一个存放操作符 op,如果找到另一个操作数b,判断操作队列队尾是否是*/,是的话执行 a(*or/)b.遍历完字符串,如果操作符队列非空,说明还有+- ...
- 用JS实现简单的屏幕录像机
本文将介绍如何用JS实现简单的屏幕录像机. 一.录制准备 创建一个按钮 <button id="recording-toggle">Start recording< ...
- 数字孪生为何需要融合GIS?以智慧城市项目为例说明
数字孪生和地理信息系统(GIS)是两个在现代科技中崭露头角的概念,它们的融合为智慧城市项目带来了革命性的机会.本文将解释数字孪生为何需要融合GIS,并以智慧城市项目为例进行说明. 数字孪生是一种虚拟模 ...
- 在WInform开发中实现工具栏/菜单的动态呈现
在Winform系统开发中,为了对系统的工具栏/菜单进行动态的控制,我们对系统的工具栏/菜单进行动态配置,这样可以把系统的功能弹性发挥到极致.通过动态工具栏/菜单的配置方式,我们可以很容易的为系统新增 ...