你搅散一池星光成为我的月亮。 —— 网络 《网络》
不管是XML配置的Context,还是Spring Boot的Context,还是Web服务中的Context,创建后都会调用AbstractApplicationContext类的refresh()方法。
定位到AbstractApplicationContext下的refresh()方法,开始分析。
整体流程如下:
@Override
public void refresh() throws BeansException, IllegalStateException {
//1
synchronized (this.startupShutdownMonitor) {
//2
prepareRefresh();
//3
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//4
prepareBeanFactory(beanFactory);
try {
//5
postProcessBeanFactory(beanFactory);
//6
invokeBeanFactoryPostProcessors(beanFactory);
//7
registerBeanPostProcessors(beanFactory);
//8
initMessageSource();
//9
initApplicationEventMulticaster();
//10
onRefresh();
//11
registerListeners();
// 12
finishBeanFactoryInitialization(beanFactory);
// 13
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
//14
resetCommonCaches();
}
}
}
分为14步,接下来我们一步一步来进行分析。
1.
synchronized (this.startupShutdownMonitor) 加锁,确保了同一时间startupShutdownMonitor的状态不发生改变。
2.
prepareRefresh() 为刷新做准备,进入方法查看:
/**
*准备此上下文以进行刷新,设置其启动日期和活动标记以及执行属性源的任何初始化
*/
protected void prepareRefresh() {
// 设置开始时间
this.startupDate = System.currentTimeMillis();
//设置激活状态
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
//初始化Context环境占位符
initPropertySources();
// 动作根据子类的自求由子类执行,然后验证是否缺失必要的properties
getEnvironment().validateRequiredProperties();
// 存储预刷新的ApplicationListeners
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// 将本地应用程序侦听器重置为预刷新状态。
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
//允许收集早期的ApplicationEvent 一旦多播器可用时就发布
this.earlyApplicationEvents = new LinkedHashSet<>();
}
3.
刷新并获得内部的 Bean Factory
4.
进入方法prepareBeanFactory()
/**
* 配置工厂的标准上下文特征,例如上下文的ClassLoader和后处理器
* @param beanFactory the BeanFactory to configure
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 告诉内部bean工厂使用上下文的类加载器等
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 使用上下文回调配置Bean工厂
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);
//BeanFactory接口未在普通工厂中注册为可解析类型
//MessageSource注册为Bean(并发现用于自动装配)
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//注册早期的后处理器以将内部bean检测为ApplicationListeners。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//检测LoadTimeWeaver并准备编织(如果找到)
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
//设置一个临时的ClassLoader以进行类型匹配。
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
//注册默认环境bean
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。
5.
postProcessBeanFactory方法源码如下
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for registering special
* BeanPostProcessors etc in certain ApplicationContext implementations.
* @param beanFactory the bean factory used by the application context
*/
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
为 Context 的子类提供后置处理 BeanFactory 的扩展能力。如果子类想在 Bean 定义加载完成后,开始初始化上下文之前做一些特殊逻辑,可以复写这个方法。
6.
invokeBeanFactoryPostProcessors()方法源码如下:
/**
* Instantiate and invoke all registered BeanFactoryPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before singleton instantiation.
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//传入Bean工厂并获取容器中的Bean工厂后置处理器(注意这里Bean工厂后置处理器还没有初始化)
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
执行 Context 中注册的 Bean Factory 后缀处理器。这里有两种后置处理器,一种是可以注册 Bean 的后缀处理器,另一种是针对 BeanFactory 进行处理的后置处理器。执行的顺序是,先按优先级执行可注册 Bean 的处理器,在按优先级执行针对 BeanFactory的处理器。由 ConfigurationClassPostProcessor 触发、由ClassPathBeanDefinitionScanner 解析并注册到 BeanFactory。
7.
registerBeanPostProcessors方法源码如下
/**
* Instantiate and register all BeanPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before any instantiation of application beans.
*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
按优先级指定顺序在 BeanFactory 中注册 Bean的后缀处理器,Bean 后置处理器可以在 Bean 初始化前、后执行处理。
8.
initMessageSource方法源码如下:
/**
* 实例化消息源
* 如果在此上下文中未定义父项,则使用父项
*/
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
初始化消息源,消息源用来支持消息的国际化
9.
/**
*初始化应用事件广播器
*如果上下文中未定义则用简单的应用事件广播器
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
初始化应用事件广播器。事件广播器用来向 ApplicationListener 通知各种应用产生的事件,是一个标准的观察者模式。
10.
onRefresh方法源码如下
/**
* Template method which can be overridden to add context-specific refresh work.
* Called on initialization of special beans, before instantiation of singletons.
* <p>This implementation is empty.
* @throws BeansException in case of errors
* @see #refresh()
*/
protected void onRefresh() throws BeansException {
//对于子类:默认情况下不执行任何操作。
}
是留给子类的扩展步骤,用来让特定的 Context 子类初始化其他的 Bean。
11.
registerListeners方法源码如下:
/**
* 添加将ApplicationListener实现为侦听器的bean
* 不会影响其他侦听器,可以将它们添加为非bean.
*/
protected void registerListeners() {
//首先注册静态指定的侦听器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
//不要在这里初始化FactoryBeans:我们需要保留所有常规bean
//未初始化,以使后处理器适用于它们!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
//现在我们终于有了一个多播器,可以发布早期的应用程序事件
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
把实现了 ApplicationListener 的 Bean 注册到事件广播器,并对广播器中的早期未广播事件进行通知。
12.
finishBeanFactoryInitialization方法源码如下:
/**
*完成此上下文的Bean工厂的初始化
*初始化所有剩余的单例beans.
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//为此上下文初始化转换服务
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));
}
//如果之前没有任何bean后处理器(例如PropertyPlaceholderConfigurer bean)注册过以下任何一个,则注册一个默认的嵌入式值解析器:
//此时,主要是为了注释属性值中的解析。
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
//尽早初始化LoadTimeWeaverAware Bean,以便尽早注册其转换器。
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
//停止使用临时ClassLoader进行类型匹配。
beanFactory.setTempClassLoader(null);
//允许缓存所有bean定义元数据,而不期望进一步的更改。
beanFactory.freezeConfiguration();
//实例化所有剩余的(非延迟初始化)单例。
beanFactory.preInstantiateSingletons();
}
冻结所有 Bean 描述信息的修改,实例化非延迟加载的单例 Bean。
13.
finishRefresh方法源码如下:
/**
*完成此上下文的刷新,调用LifecycleProcessor的 onRefresh()方法并发布
* {@link org.springframework.context.event.ContextRefreshedEvent}.
*/
protected void finishRefresh() {
//清除上下文级别的资源缓存(例如来自扫描的ASM元数据)。
clearResourceCaches();
// 为此上下文初始化生命周期处理器。
initLifecycleProcessor();
//首先将刷新传播到生命周期处理器。
getLifecycleProcessor().onRefresh();
//发布最终事件。
publishEvent(new ContextRefreshedEvent(this));
// 如果活动,请参加LiveBeansView MBean。
LiveBeansView.registerApplicationContext(this);
}
完成上下文的刷新工作,调用 LifecycleProcessor 的 onFresh() 方法以及发布 ContextRefreshedEvent 事件。
14.
/**
* Reset Spring's common reflection metadata caches, in particular the
* {@link ReflectionUtils}, {@link AnnotationUtils}, {@link ResolvableType}
* and {@link CachedIntrospectionResults} caches.
* @since 4.2
* @see ReflectionUtils#clearCache()
* @see AnnotationUtils#clearCache()
* @see ResolvableType#clearCache()
* @see CachedIntrospectionResults#clearClassLoader(ClassLoader)
*/
protected void resetCommonCaches() {
ReflectionUtils.clearCache();
AnnotationUtils.clearCache();
ResolvableType.clearCache();
CachedIntrospectionResults.clearClassLoader(getClassLoader());
}
重置公共的缓存,比如 ReflectionUtils 中的缓存、 AnnotationUtils ,ResolvableType中的缓存等等;
到此文章就结束了。