Spring源码解析 - SpringApplication run流程-refreshContext(context)源码分析
开发者可以自定义关闭钩子,通过实现 ApplicationListener 接口并监听 ContextClosedEvent 事件来实现。@Component@Override// 在这里执行自定义的关闭逻辑// 例如,关闭数据库连接池// }@Override// Add to end of list,添加处理器//前置@Override。
refreshContext源码
//SpringApplication.run 中refreshContext
refreshContext(context);
//SpringApplication.run中refreshContext实现
private void refreshContext(ConfigurableApplicationContext context) {
if (this.registerShutdownHook) {
//注册关闭钩子,其实就是注册一个事件监听器
//发事件的地方在AbstractApplicationContext.class中close()方法的doClose()中publishEvent(new ContextClosedEvent(this));
shutdownHook.registerApplicationContext(context);
}
refresh(context);
}
//SpringApplication.run中refresh实现
protected void refresh(ConfigurableApplicationContext applicationContext) {
//这里的applicationContext如果没有自己实现上下文,web类项目就是AnnotationConfigServletWebServerApplicationContext
applicationContext.refresh();
}
//AnnotationConfigServletWebServerApplicationContext一路往上继承自AbstractApplicationContext.class
//这里的AbstractApplicationContext.class就是大部分上下文的父类了。里面有close(关闭流程发ContextClosedEvent关闭事件)和refresh
public void refresh() throws BeansException, IllegalStateException {
// 确保在启动和关闭过程中只有一个线程可以进入
synchronized (this.startupShutdownMonitor) {
// 开始记录上下文刷新的步骤
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 准备上下文以进行刷新
prepareRefresh();
// 让子类刷新内部的 BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备 BeanFactory 以在当前上下文中使用,比较重要,下面有独立解析
prepareBeanFactory(beanFactory);
try {
// 允许子类对 BeanFactory 进行后处理
postProcessBeanFactory(beanFactory)
// 开始记录 Bean 后处理的步骤,看到这里
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 调用 BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 BeanPostProcessor
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 初始化消息源
initMessageSource();
// 初始化事件多播器
initApplicationEventMulticaster();
// 在特定上下文子类中初始化其他特殊 Bean
onRefresh();
// 注册监听器
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();
}
}
}
自定义关闭钩子,就是监听ContextClosedEvent事件
开发者可以自定义关闭钩子,通过实现 ApplicationListener 接口并监听 ContextClosedEvent 事件来实现。
@Component
public class MyShutdownHook implements ApplicationListener<ContextClosedEvent> {
@Override
public void onApplicationEvent(ContextClosedEvent event) {
// 在这里执行自定义的关闭逻辑
System.out.println("Application is closing...");
// 例如,关闭数据库连接池
// DataSource dataSource = event.getApplicationContext().getBean(DataSource.class);
// if (dataSource instanceof HikariDataSource) {
// ((HikariDataSource) dataSource).close();
// }
}
}
prepareBeanFactory源码解析
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置 BeanFactory 使用当前上下文的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
// 如果没有禁用 SpEL 表达式解析器,设置默认的表达式解析器
if (!shouldIgnoreSpel) {
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
// 注册一个 PropertyEditorRegistrar,用于处理资源路径的解析
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 配置 BeanFactory 的上下文回调
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 忽略某些依赖接口,避免自动注入
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);
// 注册可解析的依赖类型,使得这些接口可以在依赖注入时被解析。
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 注册早期后处理器,用于检测内部 Bean 作为 ApplicationListeners
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 检测 LoadTimeWeaver 并准备织入,如果找到
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// 设置临时类加载器用于类型匹配
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 注册默认环境 Bean,提供对象给开发者注入使用
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
小知识点:
beanFactory.registerSingleton和beanFactory.registerResolvableDependency区别
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));作用
这个在八股文里面比较常见,bean的生命周期,这里就将bean的前后置处理器添加进工厂里面了
add源码(AbstractBeanFactory.class)
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
this.beanPostProcessors.remove(beanPostProcessor);
// Add to end of list,添加处理器
this.beanPostProcessors.add(beanPostProcessor);
}
BeanPostProcessor使用源码(AbstractBeanFactory.class)自定义BeanPostProcessor也在这里被调用
调用时机
finishBeanFactoryInitialization()
└─ preInstantiateSingletons()
└─ getBean("xxx")
└─ doCreateBean()
├─ populateBean(...) // 属性填充
├─ initializeBean(bean, name, mbd) // 初始化
├─ applyBeanPostProcessorsBeforeInitialization(...) // 依次执行所有 BeanPostProcessor 的 postProcessBeforeInitialization
├─ invokeInitMethods(...) // 调用 @PostConstruct / afterPropertiesSet / init-method
└─ applyBeanPostProcessorsAfterInitialization(...) // 依次执行所有 BeanPostProcessor 的 postProcessAfterInitialization
//前置
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) { //获取父类beanPostProcessors
Object current = processor.postProcessBeforeInitialization(result, beanName); //调用前置
if (current == null) {
return result;
}
result = current;
}
return result;
}
//后置处理
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) { //获取父类beanPostProcessors
Object current = processor.postProcessAfterInitialization(result, beanName); //调用后置
if (current == null) {
return result;
}
result = current;
}
return result;
}
finishBeanFactoryInitialization最终创建bean
AbstractApplicationContext.class源码
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 1️⃣ 如果用户显式定义了一个名为 "conversionService" 且类型为 ConversionService 的 Bean,
// 就把它拿出来并设置成 BeanFactory 的 **全局类型转换器**。
// 这样后面 @Value、@ConfigurationProperties、数据绑定等场景就能统一使用。
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));
}
// 2️⃣ 兜底:如果到这一步仍没有任何 BeanFactoryPostProcessor 注册过占位符解析器,
// 就加一个最简单的解析器,支持 ${...} 占位符解析(系统变量、application.properties 等)。
// 防止后面 @Value、@ConditionalOnProperty 等注解解析失败。
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 3️⃣ **提前实例化**所有实现了 LoadTimeWeaverAware 的 Bean。
// 这些 Bean 通常需要在容器启动早期就把 ClassLoader 级别的转换器(AspectJ LTW 织入器)注册进去,
// 否则等到真正创建代理时可能来不及。
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName); // 立即触发完整生命周期:实例化 → 填充 → 初始化
}
// 4️⃣ 关闭 **临时 ClassLoader**。
// 在早期的类型匹配阶段,Spring 可能用临时 ClassLoader 做“软加载”以避免过早初始化真正的类。
// 现在类型元数据全部缓存完毕,可关闭临时加载器,减少内存占用并避免后续反射歧义。
beanFactory.setTempClassLoader(null);
// 5️⃣ **冻结** BeanDefinition:标记所有 BeanDefinition 为 **immutable**。
// 之后任何试图再次注册/删除/修改 BeanDefinition 都会抛异常,保证运行时元数据稳定。
// 这一步也为 Spring 做大量缓存优化(如类型匹配缓存)提供前提。
beanFactory.freezeConfiguration();
// 6️⃣ **开始真正干活**:
// 遍历所有 **非延迟加载的单例 BeanDefinition**,依次调用 getBean(beanName),
// 触发:实例化 → 属性填充 → 初始化(@PostConstruct → afterPropertiesSet → init-method)→
// BeanPostProcessor 前后回调 → 最终放入一级缓存 singletonObjects。
beanFactory.preInstantiateSingletons();
}
是否创建代理 AbstractAutoProxyCreator.class
✅ 循环引用场景:通过 getEarlyBeanReference() → wrapIfNecessary() 提前创建代理
✅ 正常初始化场景:在 postProcessAfterInitialization 阶段也会调用此方法
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 1. 检查是否已处理过该Bean(通过targetSourcedBeans集合)
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean; // 已处理则直接返回原始Bean
}
// 2. 检查缓存是否已确定不需要代理
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean; // 缓存标记为不需要代理
}
// 3. 检查是否为基础设施类或应跳过的类
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE); // 标记为不需要代理
return bean; // 返回原始Bean
}
// 4. 获取适用于该Bean的拦截器(通知/增强器)
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 5. 判断是否需要创建代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE); // 标记为需要代理
// 6. 创建代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass()); // 缓存代理类型
return proxy; // 返回代理对象
}
// 7. 不需要代理的情况
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean; // 返回原始Bean
}
缓存状态设置源码:
1. targetSourcedBeans
缓存
作用:标记使用了自定义 TargetSource 的 Bean
设置位置:AbstractAutoProxyCreator.postProcessBeforeInstantiation()
// AbstractAutoProxyCreator.java
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
// ...
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
// ▶ 关键设置点 ◀
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
// 创建代理并返回
Object proxy = createProxy(...);
return proxy;
}
return null;
}
2. advisedBeans
缓存
作用:记录 Bean 是否需要代理的决策结果
设置位置:
主要在 wrapIfNecessary()
方法内部设置,但有多个入口:
(1) 在跳过代理时设置
// AbstractAutoProxyCreator.wrapIfNecessary()
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE); // 标记不代理
return bean;
}
(2) 在确定需要代理时设置
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE); // 标记需要代理
// ...创建代理
}
(3) 在 shouldSkip()
方法中设置
// AspectJAwareAdvisorAutoProxyCreator.shouldSkip()
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// 切面类不需要代理
if (isAspect(beanClass)) {
this.advisedBeans.put(getCacheKey(beanClass, beanName), Boolean.FALSE);
return true;
}
return false;
}
3. proxyTypes
缓存
作用:存储最终代理对象的类型
设置位置:
在成功创建代理后立即设置:
// AbstractAutoProxyCreator.wrapIfNecessary()
if (specificInterceptors != DO_NOT_PROXY) {
Object proxy = createProxy(...);
// ▶ 关键设置点 ◀
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
4. 早期代理专用缓存(三级缓存相关)
作用:解决循环依赖时的代理一致性
设置位置:
在 AbstractAutowireCapableBeanFactory
中:
(1) 添加三级缓存
// AbstractAutowireCapableBeanFactory.doCreateBean()
protected Object doCreateBean(...) {
// ...
if (earlySingletonExposure) {
// ▶ 关键点:添加ObjectFactory到三级缓存 ◀
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// ...
}
(2) 早期代理生成
// AbstractAutowireCapableBeanFactory.getEarlyBeanReference()
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
// 委托给BeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
return ((SmartInstantiationAwareBeanPostProcessor) bp).getEarlyBeanReference(bean, beanName);
}
}
return bean;
}
(3) AOP 处理器的实现
// AbstractAutoProxyCreator.getEarlyBeanReference()
public Object getEarlyBeanReference(Object bean, String beanName) {
// ▶ 使用相同的缓存键 ◀
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// ▶ 提前设置缓存标记 ◀
this.earlyProxyReferences.put(cacheKey, bean);
// ▶ 调用相同的包装逻辑 ◀
return wrapIfNecessary(bean, beanName, cacheKey);
}
5. earlyProxyReferences
缓存
作用:跟踪已处理过早期代理的 Bean
设置位置:
// AbstractAutoProxyCreator.getEarlyBeanReference()
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// ▶ 关键设置点 ◀
this.earlyProxyReferences.put(cacheKey, bean);
return wrapIfNecessary(bean, beanName, cacheKey);
}
使用位置:在初始化后检查是否需要二次代理
// AbstractAutoProxyCreator.postProcessAfterInitialization()
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// ▶ 检查是否已处理过早期代理 ◀
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
缓存状态管理全景图
拓展bean会经过哪些缓存
普通 Bean 的缓存流向(无循环依赖、无代理)
关键结论:
所有单例 Bean 都会经过三级缓存(即使最终不需要代理)
普通 Bean 最终只存在于一级缓存
二级缓存是循环依赖专用通道(普通 Bean 不会进入)
有代理的bean的缓存流向
更多推荐
所有评论(0)