目录
finishRefresh()
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
// 为应用上下文 初始化 LifecycleProcessor
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
//推送上下文刷新完毕事件到相应的监听器
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
initLifecycleProcessor()
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//判断BeanFactory是否已经存在生命周期处理器(固定使用beanName=lifecycleProcessor
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
if (logger.isDebugEnabled()) {
logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
}
else {
// 不存在就使用默认DefaultLifecycleProcessor
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
// 把默认处理器注册到容器种
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate LifecycleProcessor with name '" +
LIFECYCLE_PROCESSOR_BEAN_NAME +
"': using default [" + this.lifecycleProcessor + "]");
}
}
}
onRefresh()
@Override
public void onRefresh() {
startBeans(true);
this.running = true;
}
private void startBeans(boolean autoStartupOnly) {
// 返回所有实现了Lifecycle bean
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
//key:如果实现了SmartLifeCycle,则为其getPhase方法返回的值,如果只是实现了Lifecycle,默认返回0
// value:相同phase的Lifecycle的集合,并将其封装到了一个LifecycleGroup中
Map<Integer, LifecycleGroup> phases = new HashMap<>();
lifecycleBeans.forEach((beanName, bean) -> {
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
// 获得当前bean 的优先级
int phase = getPhase(bean);
//分组
LifecycleGroup group = phases.get(phase);
if (group == null) {
group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
phases.put(phase, group);
}
group.add(beanName, bean);
}
});
if (!phases.isEmpty()) {
List<Integer> keys = new ArrayList<>(phases.keySet());
//排序
Collections.sort(keys);
for (Integer key : keys) {
phases.get(key).start();
}
}
}
解析:group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly) 参数解释:
phase:代表这一组lifecycleBeans的执行阶段;
timeoutPerShutdownPhase:因为lifecycleBean中的stop方法可以在另一个线程中运行,所以为了确保当前阶段的所有lifecycleBean都执行完,Spring使用了CountDownLatch,防止出现超时等待,所有这里设置了一个等待的最大时间,默认为30秒;
lifecycleBeans:所有的实现了Lifecycle的Bean;
autoStartupOnly: 手动调用容器的start方法时,为false。容器启动阶段自动调用时为true;
Lifecycle 接口 :任何Spring管理的对象都可以实现此接口。当ApplicationContext接口启动和关闭时,它会调用本容器内所有的Lifecycle实现
实现类有LifecycleProcessor与LifecycleProcessor;
LifecycleProcessor:增加了两个扩展实现发方法,LifecycleProcessor接口在Spring中的默认实现是DefaultLifecycleProcessor类,该类会为每个回调等待超时,默认超时是30秒。可以重写该类默认的参数,该类在容器内默认bean名称是lifecycleProcessor。比如修改超时时间
SmartLifecycle:又继承了Phased 类,SmartLifecycle中stop()方法有一个回调参数。所有的实现在关闭处理完成后会调用回调的run()方法,相当于开启异步关闭功能。
contextDestroyed()
当我们停止容器的时候会触发,释放资源;
/**
* 销毁根web应用程序上下文.
*/
@Override
public void contextDestroyed(ServletContextEvent event) {
closeWebApplicationContext(event.getServletContext());
ContextCleanupListener.cleanupAttributes(event.getServletContext());
}
closeWebApplicationContext(ServletContext servletContext) 方法用来将上下文置为空 ,同时把根容器也从上下文中移除;
public void closeWebApplicationContext(ServletContext servletContext) {
servletContext.log("Closing Spring root WebApplicationContext");
try {
if (this.context instanceof ConfigurableWebApplicationContext) {
((ConfigurableWebApplicationContext) this.context).close();
}
}
finally {
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
if (ccl == ContextLoader.class.getClassLoader()) {
// 置空
currentContext = null;
}
else if (ccl != null) {
currentContextPerThread.remove(ccl);
}
// 移除根容器
servletContext.removeAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
}
}东方鲤鱼