Spring IoC容器初始化主体流程

Spring IoC 的容器体系

IoC 容器是 Spring 的核心模块,是抽象了对象管理、依赖关系管理的框架解决方案。Spring 提供了很多的容器,其中 BeanFactory 是顶层容器(根容器),不能被实例化,它定义了所有 IoC 容器必须遵从的一套原则,具体的容器实现可以增加额外的功能。
比如我们常用到的 ApplicationContext,其下更具体的实现如 ClassPathXmlApplicationContext 包含了解析 xml 等一系列的内容, AnnotationConfigApplicationContext 则是包含了注解解析等一系列的内容。
Spring IoC 容器继承体系非常灵活,需要使用哪个层次用哪个层次即可,不必使用功能大而全的。

BeanFactory 顶级接口方法栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public interface BeanFactory {

/**
* 返回 FactoryBean,而不是 FactoryBean 产生的 bean
*/
String FACTORY_BEAN_PREFIX = "&";

Object getBean(String name) throws BeansException;

<T> T getBean(String name, Class<T> requiredType) throws BeansException;

Object getBean(String name, Object... args) throws BeansException;

<T> T getBean(Class<T> requiredType) throws BeansException;

<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

boolean containsBean(String name);

boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;

String[] getAliases(String name);
}

BeanFactory 容器继承体系

Bean 生命周期关键时机点

思路:创建一个类 LagouBean ,让其实现几个特殊的接口,并分别在接口实现的构造器、接口方法中断点,观察线程调用栈,分析出 Bean 对象创建和管理关键点的触发时机。

Bean 构造器执行、初始化方法(afterPropertiesSet)执行、Bean 后置处理器的 before/after 方法:

  • AbstractApplicationContext#refresh()
  • AbstractApplicationContext#finishBeanFactoryInitialization(ConfigurableListableBeanFactory)

Bean 工厂后置处理器构造器执行、PostProcessBeanFactory 方法执行:

  • AbstractApplicationContext#refresh()
  • AbstractApplicationContext#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory)

Bean 后置处理器构造器执行:

  • AbstractApplicationContext#refresh()
  • AbstractApplicationContext#registerBeanPostProcessors(ConfigurableListableBeanFactory)

最后发现 Bean 对象创建的几个关键时机点代码层级的调用都在 AbstractApplicationContext 类的 refresh 方法中,可⻅这个方法对于 Spring IoC 容器初始化来说相当关键。

Spring IoC 容器初始化主流程

由上分析可知,Spring IoC 容器初始化的关键环节就在 AbstractApplicationContext#refresh() 方法中 ,查看 refresh 方法来俯瞰容器创建的主体流程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 第一步:刷新前的预处理
prepareRefresh();

// 第二步:获取 BeanFactory,默认实现是 DefaultListableBeanFactory
// 加载 BeanDefinition 并注册到 BeanDefinitionRegistry
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();
}

...

}
}