spring容器主要有三种初始化方式,xml;注解;JavaConfig+注解形式,这里以目前最前卫的JavaConfig初始化方式来解读整个容器的初始化。(毕竟spring官方都强烈建议这种初始化方式,但可悲的是,国内的大部分中小企业还是使用传统的xml...)

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);

这是spring的入口类,spring容器的所有初始化操作都由此开始。

一、首先调用父类GenericApplicationContext的无参构造方法,实例化DefaultListableBeanFactory,这是spring的核心bean工厂,所有BeanDefinition会存放在这里,所有后置处理器也会在这里,在实现BeanFactory接口的同时也实现了BeanDefinitionRegistry接口,因此它就承担了Bean的注册管理工作。BeanDefinitionRegistry的相关接口负责注册工作,BeanFactory的相关接口负责bean的管理工作。

二、调用自身的无参构造方法,主要实例化了两个功能性对象AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner,其中最主要的是往beanDefinitionMap中put了spring自己的6个BeanDefinition,各自有各自的功能。注意这里并不是真正的Bean,BeanDefinition和后面Bean的生成有很重要的关系

  • ConfigurationClassPostProcessor

spring中最最重要的一个类,实现了BeanDefinitionRegistryPostProcessor接口,能扫描到所有的bean(通过@ComponentScan;@Bean;@Import;等注入的bean),并注册为bd

  • AutowiredAnnotationBeanPostProcessor

spring中为bean进行属性注入的后置处理器,包括解决循环依赖的问题

  • RequiredAnnotationBeanPostProcessor

处理@Required注解相关的后置处理器

  • CommonAnnotationBeanPostProcessor

通用注解的后置处理器,@Resource属性的注入也是在这当中

  • EventListenerMethodProcessor

    不清楚

  • DefaultEventListenerFactory

不清楚

三、register(annotatedClasses) 注册初始传入的配置类为bd。

四、refresh() spring容器初始化最核心的部分,这里处理了其90%的初始化工作。

  • prepareRefresh()

准备工作包括设置启动时间,是否激活标识位,初始化属性源(property source)配置

  • prepareBeanFactory(beanFactory)

准备bean工厂,这里就包括了ApplicationContextAwareProcessor(处理各种实现了*Aware 接口的bean)这个BeanPostProcessor的add

  • postProcessBeanFactory(beanFactory)

属于spring的预留接口,在后面的版本中扩展

  • invokeBeanFactoryPostProcessors(beanFactory)

spring核心方法,处理执行自定义的和spring内部定义的 BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessors,spring中那个最最重要的一个 类ConfigurationClassPostProcessor就是在这处理的,这里针对不同的来源,遵循以下执行顺序

1.自定义(手动add进来的)BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法

2.spring容器中实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry                方法

3.spring容器中实现了Ordered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法

4.spring容器中其他(实现了PriorityOrdered和Ordered之外的)BeanDefinitionRegistryPostProcessor的                                          postProcessBeanDefinitionRegistry方法

5.所有(包括自定义的和由spring管理的)BeanDefinitionRegistryPostProcessor的父类BeanFactoryPostProcessor的                    postProcessBeanFactory方法

6.所有自定义的BeanFactoryPostProcessor的postProcessBeanFactory方法

7.所有spring管理的BeanFactoryPostProcessor(实现了PriorityOrdered接口)的postProcessBeanFactory方法

8.所有spring管理的BeanFactoryPostProcessor(实现了Ordered接口)的postProcessBeanFactory方法

9.所有spring管理的BeanFactoryPostProcessor(实现了PriorityOrdered和Ordered之外的)的postProcessBeanFactory                 方法

  • registerBeanPostProcessors(beanFactory)

添加BeanPostProcessor到DefaultListableBeanFactory中的名为beanPostProcessors的List中,所以spring的所有后置处理器都是放在一个List中的

  • initMessageSource()

初始化国际化信息

  • initApplicationEventMulticaster()

初始化应用事件广播器

  • onRefresh()

属于spring的预留接口,在后面的版本中扩展

  • registerListeners()

spring event 注册事件监听器

  • finishBeanFactoryInitialization(beanFactory)

spring核心方法 实例化bean,bean的整个生命周期也从这里开始

1) 实例化之前首先去单例池中获取:getBean ---doGetBean---getSingleton,如果获取不到从singletonObjects中获取(解决bean的循环依赖问题)

2) 如果上一步没有获取到bean,就会进入bean的创建流程,执行第一次后置处理器 InstantiationAwareBeanPostProcessor#applyBeanPostProcessorsBeforeInstantiation

方法如果有返回值,将代替原本该生成的目标对象的实例,后续将只会调用所有BeanPostProcessor#postProcessAfterInitialization方法,下面的初始化操作将不再执行,这个后置处理器的经典应用场景是spring aop的代理增强剔除不必要增强的类

3) 执行第二次后置处理器SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors推断构造方法,如果有特殊的构造方法(@Autowired/@Value修饰)或者是标识首选的构造方法,则使用特殊的构造方法进行初始化,如果只有一个默认的构造方法,则返回null,就会再接下来使用默认的无参构造方法进行初始化,其实现类是AutowiredAnnotationBeanPostProcessor

4) 经过上一步之后,目标对象已经被new出来了,只是这个时侯还是对象,并不是一个bean,执行第三次后置处理器,MergedBeanDefinitionPostProcessor # postProcessMergedBeanDefinition 缓存bean实例化时须要通过注解注入的对象信息

5) addSingletonFactory,执行第四次后置处理器,SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference(其实不是第四次,因为是通过lambd表达式注入的,后续要用的时候才会用),将对象提前暴露出来,主要是为了解决spring循环依赖的问题

6) populateBean,对bean的属性赋值,这里会执行第五次后置处理器,InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation,确定是否须要注入属性,实现这个接口,返回的bean就不做后续的初始化操作了

7) 执行第六次后置处理器,InstantiationAwareBeanPostProcessor#postProcessPropertyValues,这里将完成属性注入,其中处理@AutoWired注解也是在这里来处理的

8) initializeBean,执行到这一步,对象已经完成了属性装配,可以称作为一个bean了,这里会相继执行第七次后置处理器BeanPostProcessor # postProcessBeforeInitialization;执行InitializingBean的实现;执行第八次后置处理器BeanPostProcessor # postProcessAfterInitialization,完成对bean的最后实例化阶段,最终实例化完成的单例bean将放在DefaultSingletonBeanRegistry中的一个Map中(singletonObjects)

  • finishRefresh()

至此结束整个容器的初始化过程

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐