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