目录
3、LifecycleProcessor的onRefresh
5、LiveBeansView.registerApplicationContext
一、finishRefresh
1、clearResourceCaches
Clear context-level resource caches (such as ASM metadata from scanning).清除Spring ApplicationContext级别的资源加载缓存,比如通过扫描加载注入的时候的ASM。清除的是DefaultResourceLoader的
Map<Class<?>, Map<Resource, ?>> resourceCaches
public void clearResourceCaches() {
this.resourceCaches.clear();
}
2、initLifecycleProcessor
之前在SpringIoc源码(五)- ApplicationContext(一)- 结构梳理的时候分析过,ApplicationContext实现了Lifecycle接口定义了容器的生命周期。那么在这里实现了生命周期的onRefresh方法。一般我们不会进行注册,则会初始化DefaultLifecycleProcessor 类型,并且注册名称为lifecycleProcessor的Bean。
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
}
else {
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
}
}
3、LifecycleProcessor的onRefresh
上一步初始化完成DefaultLifecycleProcessor类型,这里执行生命周期的onRefresh。
@Override
public void onRefresh() {
startBeans(true);
this.running = true;
}
private void startBeans(boolean autoStartupOnly) {
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
Map<Integer, LifecycleGroup> phases = new HashMap<>();
lifecycleBeans.forEach((beanName, bean) -> {
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
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();
}
}
}
先获取实现了Lifecycle接口的Bean,再根据不同的生命周期阶段分组,最后调用start方法,可能就会调用我们自定义的start方法。stop方法同理。 getLifecycleBeans方法如下:
protected Map<String, Lifecycle> getLifecycleBeans() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
Map<String, Lifecycle> beans = new LinkedHashMap<>();
String[] beanNames = beanFactory.getBeanNamesForType(Lifecycle.class, false, false);
for (String beanName : beanNames) {
String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName);
boolean isFactoryBean = beanFactory.isFactoryBean(beanNameToRegister);
String beanNameToCheck = (isFactoryBean ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
if ((beanFactory.containsSingleton(beanNameToRegister) &&
(!isFactoryBean || matchesBeanType(Lifecycle.class, beanNameToCheck, beanFactory))) ||
matchesBeanType(SmartLifecycle.class, beanNameToCheck, beanFactory)) {
Object bean = beanFactory.getBean(beanNameToCheck);
if (bean != this && bean instanceof Lifecycle) {
beans.put(beanNameToRegister, (Lifecycle) bean);
}
}
}
return beans;
}
4、ContextRefreshedEvent
发送ContextRefreshedEvent类型事件,Spring把事件定义为ApplicationEvent类型和我们自己的的事件(PayloadApplicationEvent)。详细可参考Spring源码-事件监听机制(实现EventListener接口)
5、LiveBeansView.registerApplicationContext
LiveBeansView.registerApplicationContext(this);
static void registerApplicationContext(ConfigurableApplicationContext applicationContext) {
String mbeanDomain = applicationContext.getEnvironment().getProperty(MBEAN_DOMAIN_PROPERTY_NAME);
if (mbeanDomain != null) {
synchronized (applicationContexts) {
if (applicationContexts.isEmpty()) {
try {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
applicationName = applicationContext.getApplicationName();
server.registerMBean(new LiveBeansView(),
new ObjectName(mbeanDomain, MBEAN_APPLICATION_KEY, applicationName));
}
catch (Throwable ex) {
throw new ApplicationContextException("Failed to register LiveBeansView MBean", ex);
}
}
applicationContexts.add(applicationContext);
}
}
}
初始化MBeanServer,完成JVM相关的监控。后续梳理与Spring Boot Actuator的JVM监控的关系。
二、Spring Boot类型的finishRefresh
SpringBoot类型的finishRefresh,比如ServletWebServerApplicationContext或者ReactiveWebServerApplicationContext类型,则会在处理父类AbstractApplicationContext的finishRefresh后,还会处理WebServer嵌入式容器相关相关的,如TomcatWebServer。下面就只看类型:
@Override
protected void finishRefresh() {
super.finishRefresh();
WebServer webServer = startWebServer();
if (webServer != null) {
publishEvent(new ServletWebServerInitializedEvent(webServer, this));
}
}
1、先回调父类,也就是上面的五步;
2、初始化WebServer(内嵌容器)
3、发送服务容器初始化事件,给监听的列表。
private WebServer startWebServer() {
WebServer webServer = this.webServer;
if (webServer != null) {
webServer.start();
}
return webServer;
}