table of Contents
- 1. The container system of Spring IoC
- Second, the key timing of the Bean life cycle
-
- 1. Analyze whether the creation of the Bean is at the time of container initialization or at the time of getBean
- 2. Analyze the constructor call
- 3. Analyze the invocation of the afterPropertiesSet initialization method of InitializingBean
- 4. Analyze the initialization and invocation of BeanFactoryPostProcessor
- 5. Analyze the initialization and invocation of BeanPostProcessor
- 6. Summary
- Three, Spring IoC container initialization main process
1. The container system of Spring IoC
The IoC container is the core module of Spring and a framework solution that abstracts object management and dependency management . Spring provides a container, which BeanFactory
is the top container (Root container) , can not be instantiated, which defines a set of principles must comply with all IoC container, particularly a container may implement additional features, such as we used to ApplicationContext
, more specifically, under such implementation ClassPathXmlApplicationContext
includes a set of xml content analysis and the like, AnnotationConfigApplicationContext
the content comprising a series of notes analysis or the like. The Spring IoC container inheritance system is very smart. You can use which level you need to use, instead of using large and complete functions.
BeanFactory
Top-level interface method stacks as follows
BeanFactory
vessel inheritance system
Connector through its design, we can see that we have always used ApplicationContext
in addition to inheriting BeanFactory
sub-interface, also inherited ResourceLoader
, MessageSource
and other interfaces, so its function also provides richer.
Here we have ClasspathXmlApplicationContext
, for example, in-depth explanation of source IoC container initialization process.
This article references "Spring Advanced Source Notes", students who need to add assistant VX: C18173184271 free access
Second, the key timing of the Bean life cycle
Idea: Create a class LagouBean, let it implement several special interfaces, and observe the thread call stack in the constructor and interface method interruption points of the interface implementation, and analyze the trigger timing of the key points of Bean object creation and management.
LagouBean
class
package com.lagou;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
/**
* @Author 应癫
* @create 2019/12/3 11:46
*/
public class LagouBean implements InitializingBean{
/**
* 构造函数
*/
public LagouBean(){
System.out.println("LagouBean 构造器...");
}
/**
* InitializingBean 接⼝实现
*/
public void afterPropertiesSet() throws Exception {
System.out.println("LagouBean afterPropertiesSet...");
}
}
BeanPostProcessor
Interface implementation class
package com.lagou;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
* @Author 应癫
* @create 2019/12/3 16:59
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor() {
System.out.println("BeanPostProcessor 实现类构造函数...");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
if("lagouBean".equals(beanName)) {
System.out.println("BeanPostProcessor 实现类 postProcessBeforeInitialization 方法被调用中......");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if("lagouBean".equals(beanName)) {
System.out.println("BeanPostProcessor 实现类 postProcessAfterInitialization 方法被调用中......");
}
return bean;
}
}
BeanFactoryPostProcessor
Interface implementation class
package com.lagou;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
/**
* @Author 应癫
* @create 2019/12/3 16:56
*/
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public MyBeanFactoryPostProcessor() {
System.out.println("BeanFactoryPostProcessor的实现类构造函数...");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory
beanFactory) throws BeansException {
System.out.println("BeanFactoryPostProcessor的实现方法调用中......");
}
}
applicationContext.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
https://www.springframework.org/schema/beans/spring-beans.xsd
">
<bean id="lagouBean" class="com.lagou.LagouBean"/>
<bean id="myBeanFactoryPostProcessor"
class="com.lagou.MyBeanFactoryPostProcessor"/>
<bean id="myBeanPostProcessor" class="com.lagou.MyBeanPostProcessor"/>
</beans>
IoC container source code analysis use case
/**
* Ioc 容器源码分析基础案例
*/
@Test
public void testIoC() {
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("classpath:applicationContext.xml");
LagouBean lagouBean = applicationContext.getBean(LagouBean.class);
System.out.println(lagouBean);
}
1. Analyze whether the creation of the Bean is at the time of container initialization or at the time of getBean
According to the breakpoint debugging, we found that the creation of the Bean is completed during the initialization of the container without setting delayed loading.
2. Analyze the constructor call
Through the above observation, we found that the call timing of the constructor is in the refresh method of the AbstractApplicationContext class ;finishBeanFactoryInitialization(beanFactory)
3. Analyze the invocation of the afterPropertiesSet initialization method of InitializingBean
Observe the call stack
above observation, we found that InitializingBean
in afterPropertiesSet method call timing is in AbstractApplicationContext class refresh method of finishBeanFactoryInitialization(beanFactory)
;
4. Analyze the initialization and invocation of BeanFactoryPostProcessor
Break points at the constructor and postProcessBeanFactory
method respectively , observe the call stack, and find
BeanFactoryPostProcessor is initialized in the refresh method of the AbstractApplicationContext
class ;invokeBeanFactoryPostProcessors(beanFactory)
postProcessBeanFactory call AbstractApplicationContext
class refresh method of invokeBeanFactoryPostProcessors(beanFactory)
;
5. Analyze the initialization and invocation of BeanPostProcessor
Break points at the constructor and postProcessBeanFactory
method respectively , observe the call stack, and find
BeanPostProcessor is initialized in the refresh method of the AbstractApplicationContext
class ;registerBeanPostProcessors(beanFactory)
postProcessBeforeInitialization call AbstractApplicationContext
class refresh method of finishBeanFactoryInitialization(beanFactory)
;
postProcessAfterInitialization call AbstractApplicationContext
class refresh method of finishBeanFactoryInitialization(beanFactory)
;
6. Summary
According to the above debugging analysis, we found that several key timing points of Bean object creation are called in
AbstractApplicationContext
the refresh method of the class . It can be seen that this method is quite critical for the initialization of the Spring IoC container . The summary is as follows:
Three, Spring IoC container initialization main process
From the above analysis shows, the Spring IoC container initialization key link in the AbstractApplicationContext#refresh()
process, we see the refresh method to overlook the main flow of container to create the specific sub-processes of the body processes come under discussion behind us.
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 第⼀步:刷新前的预处理
prepareRefresh();
/*
第一步:
获取BeanFactory;默认实现是DefaultListableBeanFactory
加载BeanDefition 并注册到 BeanDefitionRegistry
*/
ConfigurableListableBeanFactory beanFactory =
obtainFreshBeanFactory();
// 第三步:BeanFactory的预准备⼯作(BeanFactory进行一些设置,比如context的类加载器等)
prepareBeanFactory(beanFactory);
try {
// 第四步:BeanFactory准备⼯作完成后进⾏的后置处理工作
postProcessBeanFactory(beanFactory);
// 第五步:实例化并调⽤实现了BeanFactoryPostProcessor接口的Bean
invokeBeanFactoryPostProcessors(beanFactory);
// 第六步:注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执行
registerBeanPostProcessors(beanFactory);
// 第七步:初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
initMessageSource();
// 第八步:初始化事件派发器
initApplicationEventMulticaster();
// 第九步:子类重写这个⽅法,在容器刷新的时候可以⾃定义逻辑
onRefresh();
// 第⼗步:注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean
registerListeners();
/*
第十一步:
初始化所有剩下的非懒加载的单例bean
初始化创建非懒加载方式的单例Bean实例(未设置属性)
填充属性
初始化方法调用(比如调用afterPropertiesSet方法、init-method方法)
调用BeanPostProcessor(后置处理器)对实例bean进行后置处
*/
finishBeanFactoryInitialization(beanFactory);
/*
第十二步:
完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法,并且发布事件 (ContextRefreshedEvent)
*/
finishRefresh();
}
......
}
}
If you need this full version of "Spring Advanced Source Notes", you only need to support my article.
A lot of support, you can get information for free-after three consecutive years (promise: 100% free)
Quick start channel: Add assistant VX: C18173184271 Get it for free! Full of sincerity! ! !