本文主要是介绍Spring容器初始化全过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
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()
至此结束整个容器的初始化过程
这篇关于Spring容器初始化全过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!