Spring源码分析-Spring启动和Bean的加载过程
Spring的初始化,就是SpringContext的初始化。
SpringContext的初始化就是启动Spring项目时要做的第一件事。
我们测试Context初始化可以自己创建Context:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.scan("org.springframework.context.annotation6");//自己的包路径
context.refresh();
初始化上下文最重要的就是refresh方法,这里的AnnotationConfigApplicationContext的父类是:AbstractApplicationContext。
AbstractApplicationContext它也是所有*ApplicationContext的父类。
那么我们来看看refresh方法都做了什么:
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 1.刷新前准备工作,包括设置启动时间,是否激活标识位,初始化属性源(property source)配置 prepareRefresh(); // 2.创建beanFactory(过程是根据xml为每个bean生成BeanDefinition并注册到生成的beanFactory) ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); /** * 3.准备创建好的beanFactory(给beanFactory设置ClassLoader,设置SpEL表达式解析器,设置类型转化器【能将xml String类型转成相应对象】, * 增加内置ApplicationContextAwareProcessor对象,忽略各种Aware对象,注册各种内置的对账对象【BeanFactory,ApplicationContext】等, * 注册AOP相关的一些东西,注册环境相关的一些bean */ prepareBeanFactory(beanFactory); try { // 4.模板方法,为容器某些子类扩展功能所用(工厂后处理器)这里可以参考BeanFactoryPostProcessor接口的postProcessBeanFactory方法 postProcessBeanFactory(beanFactory); // 5.调用所有BeanFactoryPostProcessor注册为Bean invokeBeanFactoryPostProcessors(beanFactory); // 6.注册所有实现了BeanPostProcessor接口的Bean registerBeanPostProcessors(beanFactory); // 7.初始化MessageSource,和国际化相关 initMessageSource(); // 8.初始化容器事件传播器 initApplicationEventMulticaster(); // 9.调用容器子类某些特殊Bean的初始化,模板方法 onRefresh(); // 10.为事件传播器注册监听器 registerListeners(); // 11.初始化所有剩余的bean(普通bean) finishBeanFactoryInitialization(beanFactory); // 12.初始化容器的生命周期事件处理器,并发布容器的生命周期事件 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // 销毁已创建的bean destroyBeans(); // 重置`active`标志 cancelRefresh(ex); throw ex; } finally { // 13.重置一些缓存 resetCommonCaches(); } } }
步骤1-4都是一些准备工作
5、6步是初始化BeanPostProcessor的实现类(如果有的话)。那么这个BeanPostProcessor接口是干什么的呢,看代码:
public interface BeanPostProcessor { // 注意这个方法名称关键的是before这个单词 Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; // 注意这个方法名称关键的是after这个单词 Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; }
看到这个接口中只有两个方法,简单说就是:初始化之前做的事、初始化之后做的事。初始化什么呢,Bean。
关于BeanPostProcessor这篇文章讲的更详细:https://www.cnblogs.com/tuyang1129/p/12866484.html
这篇文章中还举了一个例子,自己创建两个bean,和一个PostProcessorBean,发现在初始化非BeanPostProcessor的时候,都会触发PostProcessorBean的Before和After方法。
这个就像是切面,可以在Bean创建之前和之后做一些事情,而被初始化的Bean是无感知的。
7-10我们后续补全(TODO)
第11步,就是我们期待已久的Bean初始化了。
我们看一下调用链:
finishBeanFactoryInitialization() --> DefaultListableBeanFactory.preInstantiateSingletons() --> 循环beanDefinitionNames中的所有bean定义,每个调用getBean进行初始化 --> AbstractBeanFactory.getBean() --> AbstractbeanFactory.doGetBean()
这里的AbstractBeanFactory.doGetBean就是Bean初始化的核心方法。
这个方法的逻辑是: 先从singletonObjects或earlySingletonObjects这两个Map中取,如果都没有,说明还没有初始化。那么就初始化,然后放入earlySingletonObjects中。

浙公网安备 33010602011771号