一 、 什么是IOC(Inversion of Control)java
IOC :控制反转,也称为依赖注入(DI)。听起来有点云里雾里,他究竟是个啥,为何Spirng中最基础的就是它?spring
咱们的项目其实都是有一个一个的Bean组成的(通俗的说就是一个一个的java类),咱们若是要使用一个Bean,那么就得在使用的地方new一个对应的实例出来,这样一来个人这个Bean是否是就依赖了另一个Bean,并且对于某一个Bean,有可能其余不少地方会用到?是否是?那么,当个人这个Bean要换一种实现,那么我是否是要将代码中其全部的地方都得改一下,这种强耦合,显然不是咱们所指望的。并且,一个Bean绝大多数时候作的事情都是同样的,若是处处new,那咱们内存中的Bean就爆炸式的增加,显然也不是咱们所指望的。tomcat
那么,咱们有没有一个东西,像tomcat容器同样,将咱们的Bean放到里面,并且每一个Bean不特殊声明的话,就只有一份,我要用的时候(程序运行的时候,写代码的时候我只要声明),让容器把这个Bean给我就是了。这个就是Spring给咱们干的事:做为一个容器,将Bean装起来,管理起来。(这里面就用到了集合,这也是为何在TinkingInJava这本书中,把咱们的集合称做容器了,我以为叫容器更合适)maven
这样一来,咱们看看,平时都是咱们要用一个Bean的时候去再使用的地方主动new一个,这种对应用的控制是由引用者本身来决定的。如今,这种应用的控制由Bean容器担当,使用者不要直接去new一个Bean,你只要告诉我你要什么Bean,我容器已经给你new好了,你要用的时候我给你就是了(一般是建立这个调用者示例的时候将被调用的Bean给他,亦或叫将这个依赖注入给它)。至于具体用哪个,这就由容器统一管理了。这就是所谓的“控制反转”--使用者只声明不控制(不new一个具体的bean),由一个统一的控制中心(Bean容器)去控制。 spring-boot
这就是控制反转,是否是很简单。并且听到这里,咱们你们都会浮出“工厂方法”这个词,对没错,Spring就是经过工厂方法实现的控制反转。接下来,咱们来简单介绍一下Spring中IOC的实现。工具
2、Spring-IOC简单介绍学习
IOC 基础包测试
|- org.springframework.beans : Spring中Bean操做的核心也是基础包,其中BeanFactory接口是Spring中访问Bean的跟接口,它提供了一种高级配置机制,可以管理任何类型的对象。this
|- 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的世界。