一.IOC的概念
IOC 即 Inversion of Control 控制反转 通俗店就是 把创建对象的权利交给Spring容器,原先是我们主动创建一个对象,现在则是把创建对象的权利交给IOC容器,需要的时候,向spring容器要就行了。
IOC容器的作用:完成了完成对象的创建和依赖的管理注入等等。
原先我们需要使用的Bean,交给了ioc容器管理,ioc容器里面存放了bean对象,那么 ioc容器需要创建什么样的bean对象?需要配置文件来表明创建的对象与对象的关系。xml properties文件可以用来描述这种关系。这样,我们创建一个spring ioc 容器,然后再创建一个对象读取ioc容器创建的bean对象与对象关系的配置文件,读取文件信息,这样就可以把bean的创建交给ioc容器了。
二、IOC容器结构
(1)BeanFactory
BeanFactory也就是Ioc容器,典型的工厂模式,在Spring里面有很多的IOC容器的实现,关系如下:
BeanFactory是最基本的IOC容器的接口,代码如下:
public interface BeanFactory {
//对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,
//如果需要得到工厂本身,需要转义
String FACTORY_BEAN_PREFIX = "&";
//根据bean的名字,获取在IOC容器中得到bean实例
Object getBean(String name) throws BeansException;
//根据bean的名字和Class类型来得到bean实例,增加了类型安全验证机制。
Object getBean(String name, Class requiredType) throws BeansException;
//提供对bean的检索,看看是否在IOC容器有这个名字的bean
boolean containsBean(String name);
//根据bean名字得到bean实例,并同时判断这个bean是不是单例
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
//得到bean实例的Class类型
Class getType(String name) throws NoSuchBeanDefinitionException;
//得到bean的别名,如果根据别名检索,那么其原名也会被检索出来
String[] getAliases(String name);
}
(2)BeanDefinition
Definition 定义的意思,用来描述Bean的。
三、IOC容器的初始化
IOC容器的初始化,分为三步 BeanDefinition的Resource定位、载入以及注册。
以XmlBeanFactory举例如下:
/**
* @author: sunzhitao
* @date: 2018/7/15 11:55
* @description: 使用XmlBeanFactory 演示ioc容器的初始化流程
*/
public class XmlBeanFactoryDemo {
public static void main(String[] args) {
/**
* IoC容器的初始化包括BeanDefinition的Resource定位、载入和注册这三个基本的过程。
*/
//1.Resource定位:根据xml配置文件创建Resource对象,该对象中包含了BeanDefinition的信息
ClassPathResource resource = new ClassPathResource("applicationContext.xml");
//DefaultListableBeanFactory
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
//创建XmlBeanDefinitionReader读取器,用于载入beandefinition。
// 传入BeanFactory,是因为需要将读取的信息回调配置给factory
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
//2,Resource的载入:XmlBeanDefinitionReader执行载入BeabDefinition的方法,
// 最后会完成Bean的载入和注册。
// 完成之后,Bean就会放入IOC容器中,需要的时候,就可以从容器中取出
reader.loadBeanDefinitions(resource);
//获取ioc容器里面的bean
MyService service = factory.getBean(MyService.class);
System.out.println("service = " + service);
System.out.println("person = " + service.addPerson());
}
}
其中,配置文件applicationContext.xml中,bean定义如下:
<!-- 配置myService-->
<bean id="myService" class="com.szt.ioc.demo.service.MyService"></bean>
被Spring IOC容器管理的bean为 MyService,代码如下:
/**
* @author: sunzhitao
* @date: 2018/7/15 15:17
* @description:
*/
public class MyService {
public Person addPerson(){
Person person = new Person();
person.setAge(18);
person.setName("miaomiao");
person.setSex("girl");
return person;
}
}
打印的结果如下:
很明显,我们通过getBean方法获得了ioc容器中的myService对象,并且能够正常使用其中的方法。