Spring 启动完成处理
Spring 启动完成处理
接上文,继续分析 spring 的启动流程。
finishRefresh()
12. 完成启动操作: AbstractApplicationContext#finishRefresh
方法如下:
protected void finishRefresh() {
// 看名字就知道了,清理初始化过程中一系列操作使用到的资源缓存
clearResourceCaches();
// 初始化LifecycleProcessor
initLifecycleProcessor();
// 这个方法的内部实现是启动所有实现了Lifecycle接口的bean
getLifecycleProcessor().onRefresh();
// 发布ContextRefreshedEvent事件
publishEvent(new ContextRefreshedEvent(this));
// 检查spring.liveBeansView.mbeanDomain是否存在,有就会创建一个MBeanServer
LiveBeansView.registerApplicationContext(this);
}
这个方法代码不多,就几个方法,我们分别来看看。
clearResourceCaches()
1. 清理资源缓存: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
的。
LifecycleProcessor
2. 处理 我们先来看看什么是 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;
}
从变量来看,这个方法仅仅只是改了一个运行状态。
ContextRefreshedEvent
事件
3. 发布 代码 publishEvent(new ContextRefreshedEvent(this))
发布了 ContextRefreshedEvent
,我们自己也可以来监听该事件。关于事件,本文并不打算深入,关于 spring 事件的详细分析,可以参考 spring 探秘之 spring 事件机制。
resetCommonCaches()
13. 清除缓存: 该方法代码如下:
protected void resetCommonCaches() {
ReflectionUtils.clearCache();
AnnotationUtils.clearCache();
ResolvableType.clearCache();
CachedIntrospectionResults.clearClassLoader(getClassLoader());
}
从方法来看,就是执行各种缓存,执行比较简单,就不深究了。