在注册配置文件后的刷新(Refresh)
在上一篇文章中,主要理清了Spring是如何(通过 register(Class<?>... componentClasses)
)注册一个或多个要处理的配置类。
但是如果不进行下一步,也就是刷新(refresh)容器,整个类是得不到完全的处理的。下图是对 refresh 方法进行的主要过程总结。会通过对每一条线上的方法进行分析和总结方法的用途。
1.prepareRefresh
prepareRefresh
是 refresh
的第一个方法,用来准备上下文环境以用来刷新(refresh)。
- 设置startupDate启动时间、设置closed为false,设置active为true.
- initPropertySources()方法,留给子类自行实现,用来在上下文环境中初始化任何占位符属性源.
- validateRequiredProperties() 用来验证所有的Proprities都是可解析的.
- 最后存储预刷新的ApplicationListeners。也就是初始化earlyApplicationEvents;
1 | protected void prepareRefresh() { |
2.obtainFreshBeanFactory
用于获取BeanFactory,在 obtainFreshBeanFactory
方法中有两个子方法。
- refreshBeanFactory方法为BeanFactory设置SerializationId
1 | protected final void refreshBeanFactory() throws IllegalStateException { |
- 使用getBeanFactory获取在register过程中已经产生的beanFactory。
1 |
|
在上一篇文章中已经分析得知,在GenericApplicationContext
的this.beanFactory
就是创建ApplicationContext
时在构造函数中创建的DefaultListableBeanFactory
。
3.prepareBeanFactory
在这个方法里面实现类对BeanFactory的内容进行基本的初始化。设置了 classLoador
、ExpressionResolver
、BeanPostProcessor
等等属性。
1 | protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { |
4.postProcessBeanFactory
这个方法的含义为对BeanFactory的后置处理,方法的实现是空的,实际含义就是让子类去实现这个方法,然后调用的时候可以对BeanFactory在标准化的初始后,进行自定义的后置处理。
5.invokeBeanFactoryPostProcessors
方法的作用就是实例化并调用所有已注册的BeanFactoryPostProcessor,也就是在这一步完成对configuration配置类中的Bean的注册过程。主要的执行方法是 PostProcessorRegistrationDelegate
中的 invokeBeanFactoryPostProcessors
方法。
在上一篇文章中提到了在 register 方法中,调用了
this.reader = new AnnotatedBeanDefinitionReader(this)
后,使用registerAnnotationConfigProcessors
注册一些相关配置类bean,如ConfigurationClassPostProcessor
等等。
首先、如果有BeanFactoryPostProcessor,则会先执行类中的 postProcessBeanDefinitionRegistry
方法
1 | for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { |
第二步、会处理在beanFactory中存在的继承BeanDefinitionRegistryPostProcessor
并且实现了PriorityOrdered
接口的类
1 | String[] postProcessorNames = |
通过Type获取BeanNames
其中使用了方法 getBeanNamesForType 用来类型为BeanDefinitionRegistryPostProcessor的Bean的名称。
1 |
|
在 doGetBeanNamesForType 中,会通过循环 this.beanDefinitionNames
内容,获取所有的 RootBeanDefinition。通过debug可以看到在此处所有的 beanDefinitionNames为
可以发现是在上一篇文章中提到的 new AnnotatedBeanDefinitionReader
的时候默认register的一些配置类。在通过使用isTypeMatch方法对所有获取到name循环比较。符合则将内容返回(只有ConfigurationAnnotationProcessor满足条件)。
执行ConfigurationAnnotationProcessor的后置方法
通过调用ConfigurationClassPostProcessor中的processConfigBeanDefinitions方法进行【构建和验证配置类】,完成对配置文件中Bean的装配,具体步骤如下:
- 获得符合条件的配置类
- 使用@Order的顺序进行排序
- 获取到处理每一个@Configuration处理类
- 处理所有@Configuration的类
- 验证所有@Coniguration的类
更具体的内容在后续再详细介绍。
第三步、会处理在beanFactory中存在的 继承 BeanDefinitionRegistryPostProcessor 并且实现了Ordered 接口的类中的
1 | // 只列出差异点 |
和第二步几乎一样,同样会对依赖排序、添加到registryProcessors中到、处理后置方法等。
最后、处理剩下的BeanDefinitionRegistryPostProcessor类
和前两步相似的重复的操作。就不展示代码了。
激活所有BeanFactoryPostProcessors
处理完所有的BeanDefinitionRegistryPostProcessors后,进行对Bean工厂的后置处理器处理。
1 | // 在前面处理过的 registryProcessors 处理器 |
上面是针对 beanFactory instanceof BeanDefinitionRegistry
的情况,如果返回false,具体内容可能稍有不容。但大致上没什么区别.
5.registerBeanPostProcessors
就像名字一样,registerBeanPostProcessors
的作用就是注册 BeanPostProcessors
,注册Bean的后置处理器。
1 | protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { |
调用PostProcessorRegistrationDelegate
的静态方法 registerBeanPostProcessors
1 | public static void registerBeanPostProcessors( |
过程类似 invokeBeanFactoryPostProcessors
的过程,实际过程分步可以整理如下:
- 获得所有的BeanPostProcessor,并注册一个
BeanPostProcessorChecker
,用来在BeanPostProcessor中创建Bean时打印信息。 - 首先注册继承了PriorityOrdered接口的BeanPostProcessor;
- 然后注册继承了Ordered接口的 BeanPostProcessor;然后注册所有的普通的 BeanPostProcessor;
- 最后注册所有的内部的BeanPostProcessor;
不管如何最后的结果都是将实现BeanPostProcessor的类注册到BeanFactory中。注册的过程就是一个CopyOnWriteArrayList添加的过程
6.initMessageSource
处理初始化消息来源MessageSource。
1 | protected void initMessageSource() { |
在 initMessageSource 过程中,做的事情很简单,主要分两步:
- 如果包含messageSource的Bean,则设置父MessageSource
- 如果不包含 messageSource 的 Bean,则创建一个 DelegatingMessageSource 的单例Bean并注册到 beanFactory 中。
7. initApplicationEventMulticaster
初始化应用事件多播器
1 | protected void initApplicationEventMulticaster() { |
和初始化MessageSource过程相似,如果包含 applicationEventMulticaster,则设置 this.applicationEventMulticaster
为容器中的多播器。如果没有,则创建,并使用beanFactory进行注册为单例的Bean。
8. onRefresh
方法用于在特定上下文子类中初始化其他特殊bean,点进方法后显示是一个空方法,是留给子类自行去实现的,去处理特殊的bean。
9. registerListeners
注册Listeners
1 | protected void registerListeners() { |
10.finishBeanFactoryInitialization
用于完成BeanFactory的初始化,在这一步完成了所有的剩余的单实例Bean的初始化过程。
1 | protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { |
主要过程包括:
- 初始化 conversionService ;
- 如果没有内置的Value解析器,则设置一个StringValueResolver解析器到beanFactory中。
- 初始化LoadTimeWeaverAware;
- 停止使用临时的ClassLoader进行类型匹配。
- 允许缓存所有bean定义元数据,而不期望进一步的更改。
- 实例化所有的剩余的、非懒加载的单实例Bean。
这里只针对第6条的实例化剩余的单实例Bean进行源码分析:
1 | beanFactory.preInstantiateSingletons(); |
经过上面的分析可以看出:在preInstantiateSingletons方法中,真正去实例化的方式是去调用 getBean
方法。
接下来分析配置文件中的Bean的注册和使用 getBean
进行真正的实例化过程进行分析。