上一篇我们解读了刷新应用上下文(中),本篇主要解读刷新应用上下文(下),老样子还是回顾下刷新的整体流程,这样就能不迷路。
此方法所在类的具体路径:org.springframework.boot.SpringApplication
private void refreshContext(ConfigurableApplicationContext context) {
if (this.registerShutdownHook) {
// 又增加一个监听器ApplicationContextClosedListener,上一文我们讲过准备刷新是11个,现在就是12个了
shutdownHook.registerApplicationContext(context);
}
refresh(context);
}
protected void refresh(ConfigurableApplicationContext applicationContext) {
// 最终实现是AbstractApplicationContext的refresh方法
applicationContext.refresh();
}
此方法所在类的具体路径:org.springframework.context.support.AbstractApplicationContext
@Override
public void refresh() throws BeansException, IllegalStateException {
// 同步的方式刷新
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 准备此上下文以进行刷新
prepareRefresh();
// 告诉子类刷新内部bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备bean工厂,以便在此上下文中使用
prepareBeanFactory(beanFactory);
try {
// 允许在上下文中子类对bean工厂进行后处理
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 调用在上下文中注册为beanFactory的后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
// 注册拦截bean创建的BeanPostProcessor
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 为此上下文初始化消息源,也就是注册DelegatingMessageSource
initMessageSource();
// 为此上下文初始化事件multicaster
initApplicationEventMulticaster();
// 初始化特定上下文子类中的其他特殊bean,比如创建内置的Servlet容器
onRefresh();
// 检查监听器bean并注册它们
registerListeners();
// 实例化所有剩余的(非惰性初始化)单例
finishBeanFactoryInitialization(beanFactory);
// 最后一步:发布相应的事件
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex);
}
// 销毁已创建的单例以避免悬空资源
destroyBeans();
// 重置“active”标志
cancelRefresh(ex);
// 将异常传播到调用方
throw ex;
} finally {
//重置Spring核心中的常见内省缓存,因为我们可能不再需要单例bean的元数据了。。。
resetCommonCaches();
contextRefresh.end();
}
}
}
本文主要讲解refresh()方法的部分内容,也就是:
// 前面已讲解,就省略了
try {
// 前面已讲解,就省略了
// 初始化特定上下文子类中的其他特殊bean,比如创建内置的Servlet容器
onRefresh();
// 检查监听器bean并注册它们
registerListeners();
// 实例化所有剩余的(非惰性初始化)单例
finishBeanFactoryInitialization(beanFactory);
// 最后一步:发布相应的事件
finishRefresh();
} catch (BeansException ex) {
}finally{
}
此方法所在类的具体路径:org.springframework.context.support.AbstractApplicationContext
@Override
protected void onRefresh() {
super.onRefresh();
try {
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
调用父类的onRefresh方法,实际是子类重新的方法,具体的实现是:org.springframework.web.context.support.GenericWebApplicationContext来完成的
public class GenericWebApplicationContext extends GenericApplicationContext
implements ConfigurableWebApplicationContext, ThemeSource {
@Nullable
private ThemeSource themeSource;
@Override
protected void onRefresh() {
// 初始化主体资源
this.themeSource = UiApplicationContextUtils.initThemeSource(this);
}
}
这里我们主要看看createWebServer()方法,看看它做了什么。
private void createWebServer() {
// 获取webServer,此时为null
WebServer webServer = this.webServer;
// 获取Servlet上下文,此时为null
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
StartupStep createWebServer = this.getApplicationStartup().start("spring.boot.webserver.create");
// 获取WebServer工厂为TomcatServletWebServerFactory
ServletWebServerFactory factory = getWebServerFactory();
createWebServer.tag("factory", factory.getClass().toString());
// 获取Servlet上下文初始化器,结果是ServletWebServerApplicationContext
// 通过工厂创建webServer
this.webServer = factory.getWebServer(getSelfInitializer());
createWebServer.end();
getBeanFactory().registerSingleton("webServerGracefulShutdown",
new WebServerGracefulShutdownLifecycle(this.webServer));
getBeanFactory().registerSingleton("webServerStartStop",
new WebServerStartStopLifecycle(this, this.webServer));
} else if (servletContext != null) {
try {
getSelfInitializer().onStartup(servletContext);
} catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context", ex);
}
}
initPropertySources();
}
调用createWebServer方法去创建内置的Servlet容器,目前SpringBoot只支持3种内置的Servlet容器:
因为我这边的依赖是:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<version>2.6.0version>
dependency>
所以这边默认是使用Tomcat容器
protected ServletWebServerFactory getWebServerFactory() {
// Use bean names so that we don't consider the hierarchy
// getBeanFactory或到的是DefaultListableBeanFactory
// 此处获取到的beanNames是tomcatServletWebServerFactory
String[] beanNames = getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);
if (beanNames.length == 0) {
throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing "
+ "ServletWebServerFactory bean.");
}
if (beanNames.length > 1) {
throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple "
+ "ServletWebServerFactory beans : " + StringUtils.arrayToCommaDelimitedString(beanNames));
}
// 返回TomcatServletWebServerFactory
return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);
}
此方法所在类的具体路径:org.springframework.context.support.AbstractApplicationContext
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 (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
getApplicationListeners()方法获取的监听器有13个,原本通过Spring工厂加载的结果是8个(参考:Alian解读SpringBoot 2.6.0 源码(一):SpringApplication对象创建(Spring工厂加载机制)),准备应用上下文之前的方法applyInitializers加载了3个监听器(参考:Alian解读SpringBoot 2.6.0 源码(七):启动流程分析之准备应用上下文),刷新应用上下文时添加了2个(参考:Alian解读SpringBoot 2.6.0 源码(八):启动流程分析之刷新应用上下文(上))最终应用上下文里的监听器如下:
获取到的监听器的名称有:
此时earlyApplicationEvents为空,故没有早期事件需要发布
此方法所在类的具体路径:org.springframework.context.support.AbstractApplicationContext
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));
}
// 判断是否有嵌入值解析器
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);
}
// 停止使用临时类加载器进行类型匹配
beanFactory.setTempClassLoader(null);
// 允许缓存所有bean定义元数据,不需要进一步更改。
beanFactory.freezeConfiguration();
// 实例化所有剩余的(非惰性初始化)单例。
beanFactory.preInstantiateSingletons();
}
此方法所在类的具体路径:org.springframework.beans.factory.support.DefaultListableBeanFactory
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
// 按注册顺序的bean定义名称的List列表
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// 创建一个迭代副本
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 触发所有非惰性单例bean的初始化
for (String beanName : beanNames) {
// 如果指定的bean对应于子bean定义,则遍历父bean定义,返回合并的RootBeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 不是抽象,是单例,并且不是懒加载的RootBeanDefinition
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// 如果是工厂bean,加上工厂bean的前"&",并获取bean
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
// 如果获取的bean是FactoryBean的实例
if (bean instanceof FactoryBean) {
// 转为FactoryBean>
FactoryBean<?> factory = (FactoryBean<?>) bean;
// 定义变量标识是否是饿汉式加载
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
} else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
// 饿汉式加载,通过beanName获取bean
getBean(beanName);
}
}
} else {
// 非工厂bean,通过beanName获取bean
getBean(beanName);
}
}
}
// 触发所有适用bean的初始化后回调
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
}
}
实例化BeanFactory中已经被注册但是未实例化的所有实例懒加载的不需要实例化,关于AbstractBeanFactory的getBean方法是非常核心的,内容也会比较多,我后面也会分单节去解读。
此方法所在类的具体路径:org.springframework.context.support.AbstractApplicationContext
protected void finishRefresh() {
// 清除上下文级别的资源缓存(例如来自扫描的ASM元数据)
clearResourceCaches();
// 为此上下文初始化声明周期处理器
initLifecycleProcessor();
// 将刷新传播到生命周期处理器
getLifecycleProcessor().onRefresh();
// 发布事件
publishEvent(new ContextRefreshedEvent(this));
// 如果处于活动状态,请参与LiveBeansView MBean。
if (!NativeDetector.inNativeImage()) {
LiveBeansView.registerApplicationContext(this);
}
}
public void clearResourceCaches() {
// 这里主要是你编写的资源
this.resourceCaches.clear();
}
public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";
protected void initLifecycleProcessor() {
// 获取到的beanFactory是DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 判断本地工厂是否含有beanName为lifecycleProcessor的bean
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
// 包含则直接从beanFactory中获取
this.lifecycleProcessor = beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
if (logger.isTraceEnabled()) {
logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
} else {
// 如果不包含,则初始化一个生命周期处理器
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
// 注册到beanFactory
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
if (logger.isTraceEnabled()) {
logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
}
}
}
beanName为lifecycleProcessor的bean是通过上面的方法beanFactory.preInstantiateSingletons()一系列操作后创建的,所以此处本地beanFactory就包含了它,也就是DefaultLifecycleProcessor
此方法所在类的具体路径:org.springframework.context.support.DefaultLifecycleProcessor
public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactoryAware {
@Override
public void onRefresh() {
startBeans(true);
this.running = true;
}
private void startBeans(boolean autoStartupOnly) {
// 获取生命周期的bean
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
Map<Integer, LifecycleGroup> phases = new TreeMap<>();
// 遍历lifecycleBeans,此处autoStartupOnly默认为true
lifecycleBeans.forEach((beanName, bean) -> {
// 如果是SmartLifecycle 的实例,并且是自动启动
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
// 获取phase
int phase = getPhase(bean);
// 如果phases中phase对应的value不存在,重新构建LifecycleGroup放入phases
phases.computeIfAbsent(
phase,
p -> new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly)
).add(beanName, bean);
}
});
if (!phases.isEmpty()) {
// phases 不为空,则进行遍历,并调用对应的LifecycleGroup的start方法
phases.values().forEach(LifecycleGroup::start);
}
}
protected Map<String, Lifecycle> getLifecycleBeans() {
// 获取到的beanFactory是DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
Map<String, Lifecycle> beans = new LinkedHashMap<>();
// 通过beanFactory获取Lifecycle类型的名称列表,不包含单例,不允许饿汉式加载
// 此处得到3个:lifecycleProcessor、webServerGracefulShutdown、webServerStartStop
String[] beanNames = beanFactory.getBeanNamesForType(Lifecycle.class, false, false);
// 遍历名称列表
for (String beanName : beanNames) {
// 返回实际的bean名称
String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName);
// 判断是否是一个工厂bean,此处是false
boolean isFactoryBean = beanFactory.isFactoryBean(beanNameToRegister);
// 如果是工厂bean,则加一个"&"
String beanNameToCheck = (isFactoryBean ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
// beanFactory包含此单例bean
// 不是工厂bean 或者 是Lifecycle的实例 或者 是SmartLifecycle的实例
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);
}
}
}
// 最终的结果:
// "webServerGracefulShutdown" -> WebServerGracefulShutdownLifecycle
// "webServerStartStop" -> WebServerStartStopLifecycle
return beans;
}
}
首先会去获取生命周期bean,然后进行过滤(得是SmartLifecycle 的实例),然后执行生命周期bean的start方法,此处的结果是:
而WebServerStartStopLifecycle会通过SimpleApplicationEventMulticaster发布ServletWebServerInitializedEvent事件,此事件获取的监听器有3个:
监听器 | 功能 |
---|---|
SpringApplicationAdminMXBeanRegistrar | 设置embeddedWebApplication为true |
DelegatingApplicationListener | 什么都没有做 |
ServerPortInfoApplicationContextInitializer | 给名称为server.ports的MapPropertySource设置local.server.port的端口值,如9000 |
此方法所在类的具体路径:org.springframework.context.support.AbstractApplicationContext
@Override
public void publishEvent(ApplicationEvent event) {
publishEvent(event, null);
}
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
ApplicationEvent applicationEvent;
// 判断event是否是ApplicationEvent的实例
if (event instanceof ApplicationEvent) {
// 是,转为ApplicationEvent
applicationEvent = (ApplicationEvent) event;
} else {
// 不是,通过PayloadApplicationEvent来装饰为applicationEvent
applicationEvent = new PayloadApplicationEvent<>(this, event);
if (eventType == null) {
eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
}
}
// 此时earlyApplicationEvents 为null
if (this.earlyApplicationEvents != null) {
// 早期事件不为null
this.earlyApplicationEvents.add(applicationEvent);
} else {
// 不为null,则广播事件
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// 父上下文不为空
if (this.parent != null) {
// 父上下文是AbstractApplicationContext的实例
if (this.parent instanceof AbstractApplicationContext) {
// 转为AbstractApplicationContext,然后发布事件
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
} else {
// 直接使用父上下文发布事件
this.parent.publishEvent(event);
}
}
}
广播事件的流程讲过很多次了,就不多说了,通过SimpleApplicationEventMulticaster发布ContextRefreshedEvent事件,最终获取的监听器有5个:
监听器 | 功能 |
---|---|
DelegatingApplicationListener | 什么都不做 |
ConditionEvaluationReportListener | 日志自动配置报告 |
ClearCachesApplicationListener | 清除反射的缓存,清除类加载器的缓存 |
SharedMetadataReaderFactoryBean | 清除元数据读取器工厂的并发引用缓存 |
ResourceUrlProvider | 先清除资源请求处理器的缓存,然后把路径对应的资源请求处理重新放入,比如/webjars/** 对应的(META-INF/resources/webjars/)和 /** 对应的(classpath[META-INF/resources/,resources/,static/,public/],ServletContext [/]) |
其实到这里通过三篇应用上下文的刷新的解读,流程基本都清楚了,但是我们在后两篇文章中有说过,关于后置处理器的调用做了什么,以及本文中的getBean方法的执行做了什么,我们没有讲解,后面我们也会分析后置处理器的调用,以及getBean方法的执行了,期待您的关注。