一 、 什么是IOC(Inversion of Control)
IOC :控制反转,也称为依赖注入(DI)。听起来有点云里雾里,他到底是个啥,为什么Spirng中最基础的就是它?
我们的项目其实都是有一个一个的Bean组成的(通俗的说就是一个一个的java类),我们如果要使用一个Bean,那么就得在使用的地方new一个对应的实例出来,这样一来我的这个Bean是不是就依赖了另外一个Bean,而且对于某一个Bean,有可能其他很多地方会用到?是不是?那么,当我的这个Bean要换一种实现,那么我是不是要将代码中其所有的地方都得改一下,这种强耦合,显然不是我们所期望的。而且,一个Bean绝大多数时候做的事情都是一样的,如果到处new,那我们内存中的Bean就爆炸式的增长,显然也不是我们所期望的。
那么,我们有没有一个东西,像tomcat容器一样,将我们的Bean放到里面,而且每个Bean不特殊声明的话,就只有一份,我要用的时候(程序运行的时候,写代码的时候我只要声明),让容器把这个Bean给我就是了。这个就是Spring给我们干的事:作为一个容器,将Bean装起来,管理起来。(这里面就用到了集合,这也是为什么在TinkingInJava这本书中,把我们的集合称作容器了,我觉得叫容器更合适)
这样一来,我们看看,平时都是我们要用一个Bean的时候去再使用的地方主动new一个,这种对应用的控制是由引用者自己来决定的。现在,这种应用的控制由Bean容器担当,使用者不要直接去new一个Bean,你只要告诉我你要什么Bean,我容器已经给你new好了,你要用的时候我给你就是了(通常是创建这个调用者示例的时候将被调用的Bean给他,亦或叫将这个依赖注入给它)。至于具体用哪一个,这就由容器统一管理了。这就是所谓的“控制反转”--使用者只声明不控制(不new一个具体的bean),由一个统一的控制中心(Bean容器)去控制。
这就是控制反转,是不是很简单。而且听到这里,我们大家都会浮出“工厂方法”这个词,对没错,Spring就是通过工厂方法实现的控制反转。接下来,我们来简单介绍一下Spring中IOC的实现。
二、Spring-IOC简单介绍
IOC 基础包
|- org.springframework.beans : Spring中Bean操作的核心也是基础包,其中BeanFactory接口是Spring中访问Bean的跟接口,它提供了一种高级配置机制,能够管理任何类型的对象。
|- org.springframework.context : Spring中上下文相关包,其中ApplicationContext接口继承自BeanFactory接口。
|- org.springframework.core : Spring和核心工具类,几乎spirng中所有的组件都要依赖它
其中,org.springframework.context.ApplicationContext接口表示Spring IoC容器,并负责实例化、配置和组装bean。容器通过读取配置元数据获取关于实例化、配置和组装哪些对象的说明。配置元数据用XML、Java注释或Java代码表示。它允许您表达组成应用程序的对象以及这些对象之间丰富的相互依赖关系。
Spring提供了ApplicationContext接口的几个实现。在独立应用程序中,通常创建ClassPathXmlApplicationContext或FileSystemXmlApplicationContext的实例。
虽然XML一直是定义配置元数据的传统格式,但是您可以指示容器使用Java注释或代码作为元数据格式。现在绝大多数都是用的Java注释,SpringBoot引入之后,更是如此,不过我们传统的Spring项目几乎都是xml配置文件,所以我们也首先从xml配置文件管理Bean的方式说起。毕竟,我们就是为了解耦,将硬编码写到配置文件中去。
ok,我们闲话少说,先看一个示例吧。
首先,我们引入依赖:
<!-- 官方建议用spring-boot来开启spring的学习,我们引入这个,主要是为了统一管理版本 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.2.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <!-- ps: 这就是maven方便的地方,spring-context中已经把core、beans都引入进来了 --> </dependencies>
引入该依赖之后,基本的依赖包均已引入,如图所示:

接下来,我们就可以开始写一个简单的测试用例了:
新建一个pojo(普通javaBean)
public class MyTestBean { private String testString = "testBean"; public String getTestString() { return testString; } public void setTestString(String testString) { this.testString = testString; } }
然后,编写beanFactoryTest.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"> <!-- 可以查看官网,将官网中的示例下载下来,然后根据实际需要更改 --> <bean id="myTestBean" class="top.djlee.spring.ioc.pojo.MyTestBean"> </bean> <!-- ps: id属性是标识单个bean定义的字符串。 class属性定义bean的类型并使用完全限定的类名。 当然,Bean的定义不仅仅如此,不过基本上这两个定义就足够我们的应用了。 --> </beans>
最后,我们来写一个主类,去测试一下是否能够注入:
public class FirstIocDemo { public static void main(String[] args) { @SuppressWarnings("resource") ApplicationContext context = new ClassPathXmlApplicationContext("beanFactoryTest.xml"); MyTestBean myTestBean = context.getBean("myTestBean",MyTestBean.class); System.out.println(myTestBean); } }
//输入内容:MyTestBean [testString=testBean]
至此,我们一个简单的SpringIOC就实现了。
通过这个示例,我们看到了,Spirng帮我们做了如下的事:
读取配置文件->根据beanFactoryTest.xml文件中的配置找到对应的类,并实例化,放到context中去->从context中拿到这个类并调用之.
当然,SpringIOC当然不仅仅如此,我们只是为了演示方便,将最简单的应用提出来,在接下来的文章中,我们就会就这这个简单的应用去尝试着分析Spring-IOC的原理,与大家一起走进Spirng-IOC的世界。
浙公网安备 33010602011771号