Spring IOC容器
概念解读:IOC控制反转容器,本身指一种设计思想。在Spring中,将原本在程序中手动创建对象的控制权交给Spring框架来管理,通过创建IOC容器管理所有的Java Bean实例,然后根据需要完成对应的实例注入。
IOC容器创建过程
在Spring中,IOC容器的顶层接口时BeanFactory,定义了IOC容器的基本功能。其中继承扩展了该接口的有很多,我们常用的就是ApplicationContext,其中常用的实现了ApplicationContext接口的类,也就是IOC容器有ClassPathXmlApplicationContext,这是通过读取XML配置文件创建的IOC容器。还有AnnotationConfigApplicationContext通过分析注解创建的IOC容器。放一个IDEA的继承结构:
-
ApplicationContext 继承了 ListableBeanFactory,这个 Listable 的意思就是,通过这个接口,我们可以获取多个 Bean,大家看源码会发现,最顶层 BeanFactory 接口的方法都是获取单个 Bean 的。
-
ApplicationContext 继承了 HierarchicalBeanFactory,Hierarchical 单词本身已经能说明问题了,也就是说我们可以在应用中起多个 BeanFactory,然后可以将各个 BeanFactory 设置为父子关系。
-
AutowireCapableBeanFactory 这个名字中的 Autowire 大家都非常熟悉,它就是用来自动装配 Bean 用的,但是仔细看上图,ApplicationContext 并没有继承它,不过不用担心,不使用继承,不代表不可以使用组合,如果你看到 ApplicationContext 接口定义中的最后一个方法 getAutowireCapableBeanFactory() 就知道了。
-
ConfigurableListableBeanFactory 也是一个特殊的接口,看图,特殊之处在于它继承了第二层所有的三个接口,而 ApplicationContext没有。这点之后会用到。
源码解析我就不做分析了,太多而且太繁琐,这里推荐一篇文章给大家,配合自己阅读源码有很大帮助:javadoop_ioc
我大概总结一下(基于XML)IOC容器创建过程:
- 当我们通过ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext(configLocation)创建容器时,通过该类的构造器会进入到创建IOC容器得核心方法**refresh()**这个方法有几个重要步骤,如下
// 1 准备刷新
this.prepareRefresh();
// 2 获取DefaultListableBeanFactory,将XML的信息解析为beanDefinition
// 并通过beanName->beanDefinition保存在Map中 《重点》
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
// 3 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
this.prepareBeanFactory(beanFactory);
// 4 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
this.postProcessBeanFactory(beanFactory);
// ...
// 5 注册所有的BeanFactory后置处理器,并调用 《重点》
this.invokeBeanFactoryPostProcessors(beanFactory);
// 6 注册所有的Bean后置处理器 《重点》
this.registerBeanPostProcessors(beanFactory);
// ...
//....
// 7 完成剩下的所有单实例Bean的实例化 《重点》
this.finishBeanFactoryInitialization(beanFactory);
// ...
-
2 获取DefaultListableBeanFactory,将XML的信息解析为beanDefinition,这个步骤是重点,总结一下:
- 实例化一个DefaultListableBeanFactory,然后拿着这个BeanFactory去加载BeanDefinitions
javadoop_ioc:ApplicationContext 继承自 BeanFactory,但是它不应该被理解为 BeanFactory 的实现类,而是说其内部持有一个实例化的 BeanFactory(DefaultListableBeanFactory)
- 将路径信息转化为Resource,找到XML配置文件,将其转化为Document对象
- 然后先解析默认的默认的命名空间,在解析自定义的命名空间
parseDefaultElement(ele, delegate):
<import />
、<alias />
、<bean />
和<beans />
parseCustomElement(ele):其他标签比如
<mvc />
、<task />
、<context />
、<aop />
等- 拿默认的命名空间bean标签为例,会将标签中的信息解析为beanDefinition,beanName和aliasesArray,并将其设置到BeanDefinitionHolder对象当中
beanDefinition:bean定义信息,即对象的设置的各种属性信息,翻看一下BeanDefinition接口源码即可
beanName:即bean对象的名字,XML配置的id或者name,注意是全类名
aliasesArray:bean对象的别名
- 最后DefaultListableBeanFactory通过beanDefinition注册Bean,就是通过**beanDefinitionMap.put(beanName, beanDefinition)将信息保存在一个Map当中,同时会通过beanDefinitionNames.add(beanName)**将注册过的beanName保存在一个ArrayList当中
- 最后就完成了初始化 Bean 容器,但未初始化Bean,
<bean />
配置也相应的转换为了一个个 BeanDefinition,然后注册了各个 BeanDefinition 到注册中心,并且发送了注册事件。
-
7 完成剩下的所有单实例Bean的实例化 《重点》,本篇讲解IOC容器,所有其他重点这里不总结了
- 通过**getBean(beanName)**创建实例,如果已经创建了(通常是我们拿到容器,调用getBean时),直接返回即可
- 先初始化所有depend-on的bean
- 然后考虑通过**InstantiationAwareBeanPostProcessor **返回一个代理对象
- 没有返回代理对象则创建一个普通实例Bean,然后设置属性值,初始化bean
initializeBean(初始化bean):包括init-method 、 InitializingBean 、BeanPostProcessor 等
- 最后返回实例bean即可
更多细节参见javadoop_ioc
Bean对象生命周期
如下图:
我们可以通过打印日志的方式验证Bean对象的整个生命周期,基于XML的方式:
- 首先需要写一个Bean对象MyBean,实现DisposableBean(用于对象销毁做某些操作);InitializingBean(用于属性注入后做某些初始化操作),;BeanFactoryAware和BeanNameAware(用于设置BeanFactory和BeanName)这四个接口:
public class MyBean implements DisposableBean, InitializingBean, BeanFactoryAware, BeanNameAware {
private String name;
public void test(){
System.out.println("16 调用MyBean的方法...");
}
public MyBean() {
System.out.println("6 实例化bean...");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("8 为Bean注入属性...");
this.name = name;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("10 执行BeanFactoryAware的setBeanFactory方法...");
}
@Override
public void setBeanName(String s) {
System.out.println("9 执行BeanNameAware的setBeanName方法...");
}
@Override
public void destroy() throws Exception {
System.out.println("17 执行DisposableBean的destroy方法...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("12 执行InitializingBean的afterPropertiesSet方法...");
}
public void initInXml(){
System.out.println("13 执行<bean>定义的init-method方法...");
}
public void destroyInXml(){
System.out.println("18 执行<bean>定义的destroy-method方法...");
}
}
- 然后我们写一个BeanPostProcessor接口的实现类MyBeanPostProcessor(用于Bean对象初始化前后做某些操作):
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor() {
super();
System.out.println("3 实例化自定义的BeanPostProcessor实现类MyBeanPostProcessor...");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("11 调用MyBeanPostProcessor的postProcessBeforeInitialization方法...");
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("14 调用MyBeanPostProcessor的postProcessAfterInitialization方法...");
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
- 然后我们写一个BeanFactoryPostProcessor接口的实现类MyBeanFactoryPostProcessor(用于对BeanFactory做某些操作):
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public MyBeanFactoryPostProcessor() {
super();
System.out.println("1 实例化BeanFactoryPostProcessor的实现类MyBeanFactoryPostProcessor...");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("2 调用MyBeanFactoryPostProcessor的postProcessBeanFactory方法...");
}
}
- 然后我们写一个InstantiationAwareBeanPostProcessorAdapter类的子类MyInstantiationAwareBeanPostProcessor(用于Bean对象实例化前和Bean对象初始化后做某些操作):
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
public MyInstantiationAwareBeanPostProcessor() {
super();
System.out.println("4 实例化InstantiationAwareBeanPostProcessorAdapter的实现类MyInstantiationAwareBeanPostProcessor...");
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("5 调用MyInstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法...");
return super.postProcessBeforeInstantiation(beanClass, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("15 调用MyInstantiationAwareBeanPostProcessor的postProcessAfterInitialization方法...");
return super.postProcessAfterInitialization(bean, beanName);
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
System.out.println("7 调用MyInstantiationAwareBeanPostProcessor的postProcessPropertyValues方法...");
return super.postProcessPropertyValues(pvs, pds, bean, beanName);
}
}
- 配置XML文件application.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="MyBean" class="com.springlearn.MyBean" init-method="initInXml" destroy-method="destroyInXml">
<property name="name" value="lihua"/>
</bean>
<bean id="MyBeanFactoryPostProcessor" class="com.springlearn.MyBeanFactoryPostProcessor"/>
<bean id="MyBeanPostProcessor" class="com.springlearn.MyBeanPostProcessor"/>
<bean id="MyInstantiationAwareBeanPostProcessor" class="com.springlearn.MyInstantiationAwareBeanPostProcessor"/>
</beans>
- 编写测试类springApplication:
public class springApplication {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext xmlIOC = new ClassPathXmlApplicationContext("application.xml");
MyBean myBean = xmlIOC.getBean(MyBean.class);
myBean.test();
xmlIOC.registerShutdownHook();
}
}
- 最终运行效果:
1 实例化BeanFactoryPostProcessor的实现类MyBeanFactoryPostProcessor...
2 调用MyBeanFactoryPostProcessor的postProcessBeanFactory方法...
3 实例化自定义的BeanPostProcessor实现类MyBeanPostProcessor...
4 实例化InstantiationAwareBeanPostProcessorAdapter的实现类MyInstantiationAwareBeanPostProcessor...
5 调用MyInstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法...
6 实例化bean...
7 调用MyInstantiationAwareBeanPostProcessor的postProcessPropertyValues方法...
8 为Bean注入属性...
9 执行BeanNameAware的setBeanName方法...
10 执行BeanFactoryAware的setBeanFactory方法...
11 调用MyBeanPostProcessor的postProcessBeforeInitialization方法...
12 执行InitializingBean的afterPropertiesSet方法...
13 执行<bean>定义的init-method方法...
14 调用MyBeanPostProcessor的postProcessAfterInitialization方法...
15 调用MyInstantiationAwareBeanPostProcessor的postProcessAfterInitialization方法...
16 调用MyBean的方法...
17 执行DisposableBean的destroy方法...
18 执行<bean>定义的destroy-method方法...