深入理解Spring源码:启动过程完结篇——启动完成后的行为剖析
注:本系列源码分析基于spring 5.2.2.RELEASE,本文的启动流程针对于
annotation
注解方式,gitee仓库链接:spring-framework.
接上文,继续分析spring的启动流程。
12. 完成启动操作: finishRefresh()
AbstractApplicationContext#finishRefresh
方法如下:
protected void finishRefresh() {
// 看名字就知道了,清理初始化过程中一系列操作使用到的资源缓存
clearResourceCaches();
// 初始化LifecycleProcessor
initLifecycleProcessor();
// 这个方法的内部实现是启动所有实现了Lifecycle接口的bean
getLifecycleProcessor().onRefresh();
// 发布ContextRefreshedEvent事件
publishEvent(new ContextRefreshedEvent(this));
// 检查spring.liveBeansView.mbeanDomain是否存在,有就会创建一个MBeanServer
LiveBeansView.registerApplicationContext(this);
}
这个方法代码不多,就几个方法,我们分别来看看。
1. 清理资源缓存:clearResourceCaches()
clearResourceCaches()
方法内容如下:
public class DefaultResourceLoader implements ResourceLoader {
private final Map<Class<?>, Map<Resource, ?>> resourceCaches
= new ConcurrentHashMap<>(4);
public void clearResourceCaches() {
this.resourceCaches.clear();
}
// 省略了这个类的好多代码
...
}
这个方法就是用来清理resourceCaches
的,这是个Map
,里面存入的内容是Resource
。
那什么是Resource
呢?在前面介绍扫描包的过程中,我们会先把class文件读取出来,转换成Resource
后再进一步处理,常见的Resource
类型有FileSystemResource
、UrlResource
等,resourceCaches
就是存放这些Resource
的。
2. 处理 LifecycleProcessor
我们先来看看什么是LifecycleProcessor
:
/**
* 处理容器的启动与关闭操作
*/
public interface LifecycleProcessor extends Lifecycle {
/**
* 容器启动完成时调用
*/
void onRefresh();
/**
* 容器关闭时调用
*/
void onClose();
}
这个接口用来处理容器处理容器的启动与关闭操作,比如我们自己实现该接口,然后重写onRefresh()
与onClose()
,以便在容器启动与关闭时做一些操作,像这样:
@Component
public class MyLifecycleProcessor implements LifecycleProcessor {
@Override
public void onRefresh() {
System.out.println("容器启动");
}
@Override
public void onClose() {
System.out.println("容器关闭");
}
}
与LifecycleProcessor
相关的方法有两个:initLifecycleProcessor()
、getLifecycleProcessor()
,我们一起一为看看这两个方法:
AbstractApplicationContext
private LifecycleProcessor lifecycleProcessor;
/**
* 初始化 LifecycleProcessor
*/
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 存在,直接使用
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
}
// 不存在则创建,默认使用DefaultLifecycleProcessor
else {
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
}
}
/**
* 返回 lifecycleProcessor
*/
LifecycleProcessor getLifecycleProcessor() throws IllegalStateException {
if (this.lifecycleProcessor == null) {
throw new IllegalStateException(...);
}
return this.lifecycleProcessor;
}
initLifecycleProcessor
所做的就是设置AbstractApplicationContext#lifecycleProcessor
属性,如果beanFactory
中存在initLifecycleProcessor
则直接使用,否则就创建一个。
getLifecycleProcessor()
仅仅只是返回了AbstractApplicationContext#lifecycleProcessor
属性。
在getLifecycleProcessor().onRefresh()
中,还调用了onRefresh()
方法,我们一起来看看DefaultLifecycleProcessor#onRefresh
做了什么:
@Override
public void onRefresh() {
startBeans(true);
this.running = true;
}
从变量来看,这个方法仅仅只是改了一个运行状态。
3. 发布ContextRefreshedEvent
事件
代码 publishEvent(new ContextRefreshedEvent(this))
发布了ContextRefreshedEvent
,我们自己也可以来监听该事件。关于事件,本文并不打算深入,关于spring事件的详细分析,可以参考spring探秘之spring 事件机制。
13. 清除缓存: resetCommonCaches()
该方法代码如下:
protected void resetCommonCaches() {
ReflectionUtils.clearCache();
AnnotationUtils.clearCache();
ResolvableType.clearCache();
CachedIntrospectionResults.clearClassLoader(getClassLoader());
}
从方法来看,就是执行各种缓存,执行比较简单,就不深究了。
本系列的其他文章
【spring源码分析】spring源码分析系列目录