概要
过度
上面我们宏观介绍了refresh()
的基本思路:

接下来我们按照框出来的四个部分依次介绍,本节介绍的是Context
的设置。
内容简介
本节介绍对context
的设置,主要包括:
- 初始化
MessageSource
,目的是国际化和本土化的配置 - 初始化事件广播的相关组件
- 将配置的监听器进行注册
其中,我们主要关注的是整个ApplicationContext
的工作流程,所以主要对后两点进行介绍,后面如果涉及国际化和本土化的东西,再回头看。
所属环节
context
相关设置。
上下环节
上文: 完成了对BeanFactory
的设置
下文:刷新完成,对BeanFactory
中所有的单例进行实例化以校验配置是否正确。并发布启动事件
源码解析
入口
还是从我们最开始的refresh()
函数开始:
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 准备此 ApplicationContext
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// BeanFactory 的初始化及对应的 BD 的加载
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 对 BeanFactory 中的一些和上下文相关的属性进行设置和同步。
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 定义了一个钩子,供子类实现
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 调用 BeanFactory 的后处理器对其进行处理
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册那些拦截 Bean 创建的后处理器
// 注意,上面 invokeBeanFactoryPostProcessors() 各种实例化各种注册,操作的都是针对 factory 的后处理器。这里才是针对 bean
// 的后处理器
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 初始化本 context 的 Message 源【国际化和本土化】【将对应的信息符号转化成对应的语言提示】
// TODO 没啥需要,最后再看
initMessageSource();
// Initialize event multicaster for this context.
// 初始化事件广播相关的东西
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 子实现类根据各自情况实现其他的特殊 Bean 的处理
// 算是留下的一个钩子
onRefresh();
// Check for listener beans and register them.
// 找出所有可注册的监听器并注册成有效的监听器,完成初始化后将之前缓存的事件散发出去
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 将剩余的非懒加载的单例加载一下
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 完成启动,散发相应事件
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
本节我们主要对initApplicationEventMulticaster()
,registerListeners()
进行介绍。
初始化事件广播组件
这里主要介绍initApplicationEventMulticaster()
函数:
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 有自行定制就用 BeanFactory 中定制的,如果没有就用默认的。
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
} else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
思路就是如果在BeanFactory
中有注册,就用注册的,如果没有,就用默认的实现自己生成一个。注意,自己补充上之后会在BeanFactory
中注册,方便用户自己通过依赖注入获得。
注册事件监听器
// 我们之前把对应的监听器都放到 applicationListeners ,这里注册成正经发挥总用的监听器
// 当然,我们创建的 BD 里面类型合适的,也一同完成注册。完成注册后将积压的那些事件散发出去。
// 注意:对于在后面又增加的 BD ,context 增加了一个后处理器,发现是监听器的实例初始化了,也会自动给注册进去。
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
将自己编码在ApplicationContext
中的监听器注册,然后把BeanFactory
中符合条件的也进行注册。
注意,前面在配置BeanFactory
时加了一个后处理器,如果发现监听器类型的实例,会自动注册到上下文。由此保证所有的监听器都能被发现并将事件通知到位。
网友评论