【Spring】ApplicationContext 二 AbstractApplicationContext
前言
AbstractApplicationContext
,抽象基类,几乎实现了顶层接口定义的所有方法,其中最核心的便是 refresh
方法,这里提供了模板方法的设计模型,将容器刷新的步骤拆解成 13
步并依次给出对应的实现,同时也允许子类去复写
版本
Spring 5.3.x
AbstractApplicationContext#refresh
/**
* 核心方法:AbstractApplicationContext 定义的模板方法
* 加载(刷新)容器的配置,意味着整个容器的启动
*/
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
}
catch (BeansException ex) {
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
}
方法概览,一个个了解细节:
prepareRefresh
protected void prepareRefresh() {
// 设置时间戳、标识位
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
// 属性源配置,由子类实现,比如 web 环境加载 Servlet 属性等
initPropertySources();
// 校验所有 required 属性存在
getEnvironment().validateRequiredProperties();
// 初始化早期事件相关
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
this.earlyApplicationEvents = new LinkedHashSet<>();
}
前置处理
- 设置 时间戳、标识位
- 占位符解析源配置
- 环境属性必填性校验
- 早期事件相关
obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 获取 BeanFactory 实例,由子类实现
refreshBeanFactory();
return getBeanFactory();
}
refreshBeanFactory
,子类实现,比如可刷新容器创建新的BeanFactory
getBeanFactory
,返回准备好的BeanFactory
prepareBeanFactory
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置类加载器、表达式解析类、ResourceEditorRegistrar
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// ApplicationContextAwareProcessor 用来处理各种 aware 回调
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 忽略以下类的自动装配
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// 以下 bean 是容器默认注册的,之所以我们可以直接注入这些实例使用
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// ApplicationListenerDetector 用来 注册、移除 自定义的事件监听器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 静态织入 相关
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 分别注册 environment systemProperties systemEnvironment 单例
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
这里是对上一个步骤获取的 BeanFactory
进行配置处理,主要是一些组件的配置和 bean
实例的注册等
- 配置
ClassLoader
StandardBeanExpressionResolver
等,StandardBeanExpressionResolver
是Spring
对SpEL
解析相关类的收口 - 注册了
ApplicationContextAwareProcessor
,这个后处理器负责Aware
相关回调,用于给对应的示例注入ApplicationContext
Environment
等属性 - 依赖处理相关、静态织入相关
- 注册
ApplicationListenerDetector
和environment
systemProperties
等单例,其中我们自定义的ApplicationListener
类型的实例会被ApplicationListenerDetector
注册到容器中的
SpEL 相关,可以参考下文
【Spring】SpEL 二 PropertyAccessor 相关(BeanFactoryAccessor EnvironmentAccessor)
postProcessBeanFactory
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
这里允许进一步对 BeanFactory
进行拓展处理,可见子类
invokeBeanFactoryPostProcessors
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// 静态织入 相关 ...
}
此处是比较核心的一个步骤,关键步骤发生在 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())
,它的代码较长,此处做一个总结:
- 其中,
BeanDefinitionRegistryPostProcessor
是BeanFactoryPostProcessor
的子类,前者是针对BeanDefinitionRegistry
的后处理,对应方法BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
,后者是针对BeanFactory
的后处理,对应方法BeanFactoryPostProcessor#postProcessBeanFactory
- 上面代码中
getBeanFactoryPostProcessors()
方法返回的是所有自行add
的BeanFactoryPostProcessor
,大多数情况我们不会自行添加(即便添加也是以注册bean
组件的形式),因为这里一般为空,但如果存在,它的优先级会最高 - 关于上述方法执行的优先级以及详细的执行顺序总结如下
- 1)所有 自行添加 的
BeanDefinitionRegistryPostProcessor
的postProcessBeanDefinitionRegistry
方法 - 2)所有 容器中 实现了
PriorityOrdered
接口的BeanDefinitionRegistryPostProcessor
的postProcessBeanDefinitionRegistry
方法 - 3)所有 容器中 实现了
Ordered
接口的BeanDefinitionRegistryPostProcessor
的postProcessBeanDefinitionRegistry
方法 - 4)容器中 其他
BeanDefinitionRegistryPostProcessor
的postProcessBeanDefinitionRegistry
方法 - 5)所有 自行添加 的
BeanDefinitionRegistryPostProcessor
的postProcessBeanFactory
方法 - 6)所有 自行添加 的
BeanFactoryPostProcessor
的postProcessBeanFactory
方法 - 7)所有 容器中 实现了
PriorityOrdered
接口的BeanFactoryPostProcessor
的postProcessBeanFactory
方法 - 8)所有 容器中 实现了
Ordered
接口的BeanFactoryPostProcessor
的postProcessBeanFactory
方法 - 9)容器中 其他
BeanFactoryPostProcessor
的postProcessBeanFactory
方法
总结来说就是:
自行添加
优先于容器中的实例
BeanDefinitionRegistryPostProcessor
优先于BeanFactoryPostProcessor
@PriorityOrdered
优先于@Ordered
优先于其他
postProcessBeanDefinitionRegistry
方法优先于postProcessBeanFactory
其中,最最重要的 BeanDefinitionRegistryPostProcessor
的就是 ConfigurationClassPostProcessor
,关于它的内容不少,可移步参考 Spring Configuration
专栏
registerBeanPostProcessors
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
这里,是注册容器中所有的 BeanPostProcessor
,这里不贴具体源码,简述流程:
- 开头先注册了一个
BeanPostProcessorChecker
,这个处理器主要是针对没有被所有BeanPostProcessor
全处理的bean
(比如在这些BeanPostProcessor
之前初始化的bean
),输出一条info
日志 - 然后按照如下顺序注册
BeanPostProcessor
- 1)实现了
PriorityOrdered
接口的BeanPostProcessor
- 2)实现了
Ordered
接口的BeanPostProcessor
- 3)其余的
BeanPostProcessor
- 4)实现了
PriorityOrdered
接口的MergedBeanDefinitionPostProcessor
- 5)实现了
Ordered
接口的MergedBeanDefinitionPostProcessor
- 6)其余的
MergedBeanDefinitionPostProcessor
- 7)最后重新注册一个
ApplicationListenerDetector
initMessageSource
初始化 messageSource
属性,默认为 DelegatingMessageSource
,实现国际化相关能力
关于 MessageSource(国际化),可阅读下文
【源码】关于 Spring 国际化 MessageSource
initApplicationEventMulticaster
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 如果已经注册,则获取(创建)对应的 bean 实例
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
// ...
}
// 否则,创建 SimpleApplicationEventMulticaster 并注册为单例
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
// ...
}
}
事件组播器
相关,如果不自行设置,则默认实例化一个SimpleApplicationEventMulticaster
Spring
事件相关,可以参考下文:
【源码】Spring —— ApplicationEvent ApplicationListener ApplicationEventMulticaster
onRefresh
protected void onRefresh() throws BeansException {
}
由子类实现,比如初始化一些自定义的 bean
registerListeners
protected void registerListeners() {
// 注册 add 进来的监听器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 注册所有容器中的监听器 bean
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// ...
}
监听器的注册
- 先注册
addApplicationListener
方法添加进来的 监听器 - 再取出容器中
ApplicationListener
类型的bean
名称,将它们添加到 事件组播器 中 - 值得一提的是,这个方法的工作跟之前注册的
ApplicationListenerDetector
后处理器差不多,只是此处并没有实例化这些bean
,而只是注册了对应的beanName
,但不要担心会重复监听,因为ApplicationEventMulticaster
做了判断处理
finishBeanFactoryInitialization
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 先创建 ConversionService(如果存在)
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// 如果没有对应的占位符(${})解析器,则由 AbstractPropertyResolver.resolvePlaceholders 解析
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 静态织入 相关
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
beanFactory.setTempClassLoader(null);
beanFactory.freezeConfiguration();
// 核心步骤:非 Lazy 单例注册
beanFactory.preInstantiateSingletons();
}
- 如果我们有自定义
ConversionService
,这个地方就会注册进去,作为beanFactory
的标准转换服务 - 如果没有指定值解析器,则此处委托给
Environment
,Environment
的相关文章有提到,此处的调用链实际是Environment -> PropertySourcesPropertyResolver -> PropertyPlaceholderHelper
- 静态织入相关,略
- 最后就是最关键的步骤,非
Lazy
单例的初始化,此方法详情可参考文章:
【源码】Spring —— BeanFactory 解读 5 DefaultListableBeanFactory
finishRefresh
至此,主要的步骤都完了,该方法执行:
Lifecycle
相关- 发布
ContextRefreshedEvent
事件
resetCommonCaches
最后一步,各种缓存清除
总结
归纳一下这章节的内容,我们平时开发过程中可能不会陌生的点:
- 了解到
Aware
感知回调接口机制及时机 - 比较关键的一个点:
BeanFactoryPostProcessor
的执行时机及顺序,这对于我们进行BeanDefinition
BeanFactory
相关拓展十分有用,参考ConfigurationClassPostProcessor
- 同样的,
BeanPostProcessor
的执行时机与顺序也十分重要,虽然本文并没有详细讲述时机与顺序(但在前后的章节中有详细讲述),如果要依此对bean
实例进行自定义的拓展,了解它们是必须的 国际化相关
,如果业务涉及便可深入了解事件驱动相关
,这其实是个独立且重要的模块,首先事件驱动
本身就是一种重要的思想,我们完全可以记住Spring
的实现进行自定义的使用与拓展,比如SpringBoot
就完美的应用了事件机制监听器
的注册,了解自定义的监听器是何时、如何被注册进容器的- 最后就是距离我们最近的东西:单例初始化,到容器伊始的
BeanDefinition
收集,到中期可能的BeanDefinition
新增、变更,到该阶段基于BeanDefinition
构造bean
实例与后处理等一系列繁杂的过程
上一篇:【Spring】ApplicationContext 一 接口梳理
下一篇:【Spring】ApplicationContext 三 AnnotationConfigApplicationContext