Spring 容器刷新流程(refresh)源码全解
🔄 Spring 容器刷新流程(refresh)源码全解
文章目录
- 🔄 Spring 容器刷新流程(refresh)源码全解
- 🎯 一、Spring 容器启动的整体流程概览
- 🔄 Spring 容器启动全景图
- ⏱️ 启动阶段时间线
- 🔄 二、refresh 方法的执行阶段全解析
- 🚀 refresh() 方法核心框架
- 🔧 阶段1:prepareRefresh() - 准备刷新
- 🏗️ 阶段2:obtainFreshBeanFactory() - 获取BeanFactory
- ⚙️ 阶段3:prepareBeanFactory() - 配置BeanFactory
- ⚙️ 三、BeanFactoryPostProcessor 与 BeanPostProcessor 初始化
- 🔄 BeanFactoryPostProcessor 调用流程
- 🛠️ BeanPostProcessor 注册流程
- 📢 四、事件、多播、监听器注册阶段
- 🔊 事件系统初始化流程
- 👂 监听器注册机制
- 🎯 子类扩展点:onRefresh()
- 🔍 五、源码路径追踪:AbstractApplicationContext
- 📊 refresh() 方法执行流程图
- 🔎 关键阶段源码深度分析
- 🐛 六、调试日志与启动问题排查
- 📝 启动日志输出示例
- 🔧 调试技巧与工具
- ⚠️ 常见启动问题排查
- 💎 七、总结:Spring 容器的启动脉络
- 🎯 核心启动流程总结
- 🚀 性能优化建议
- 🔮 高级特性与最佳实践
🎯 一、Spring 容器启动的整体流程概览
🔄 Spring 容器启动全景图
ApplicationContext 启动流程总览:
⏱️ 启动阶段时间线
容器启动关键节点时序:
timelinetitle Spring 容器启动时间线section 准备阶段环境准备 : 初始化属性源BeanFactory创建 : 加载Bean定义BeanFactory配置 : 配置类加载器section 后处理阶段BeanFactory后处理 : 执行BeanFactoryPostProcessorBean后处理注册 : 注册BeanPostProcessor消息源初始化 : 国际化支持section 事件阶段事件广播器 : 初始化事件多播器特殊Bean初始化 : 子类扩展点监听器注册 : 注册事件监听器section 完成阶段单例预实例化 : 初始化非懒加载单例上下文刷新完成 : 发布刷新事件生命周期启动 : 启动Lifecycle Bean
🔄 二、refresh 方法的执行阶段全解析
🚀 refresh() 方法核心框架
AbstractApplicationContext#refresh() 完整源码结构:
@Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 阶段1: 准备刷新上下文prepareRefresh();// 阶段2: 获取BeanFactory并加载Bean定义ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 阶段3: 准备BeanFactory(配置类加载器、添加BeanPostProcessor等)prepareBeanFactory(beanFactory);try {// 阶段4: 后处理BeanFactory(子类扩展点)postProcessBeanFactory(beanFactory);// 阶段5: 调用BeanFactory后处理器invokeBeanFactoryPostProcessors(beanFactory);// 阶段6: 注册Bean后处理器registerBeanPostProcessors(beanFactory);// 阶段7: 初始化消息源(国际化)initMessageSource();// 阶段8: 初始化事件广播器initApplicationEventMulticaster();// 阶段9: 初始化特殊Bean(子类扩展)onRefresh();// 阶段10: 注册事件监听器registerListeners();// 阶段11: 实例化所有非懒加载单例BeanfinishBeanFactoryInitialization(beanFactory);// 阶段12: 完成刷新,发布上下文刷新事件finishRefresh();} catch (BeansException ex) {// 阶段13: 销毁已创建的单例BeandestroyBeans();// 阶段14: 重置激活标志cancelRefresh(ex);throw ex;}}
}
🔧 阶段1:prepareRefresh() - 准备刷新
容器启动前的准备工作:
protected void prepareRefresh() {// 1. 记录启动时间戳this.startupDate = System.currentTimeMillis();this.closed.set(false);this.active.set(true);// 2. 初始化上下文环境中的占位符属性源initPropertySources();// 3. 验证必需属性getEnvironment().validateRequiredProperties();// 4. 存储早期应用事件this.earlyApplicationEvents = new LinkedHashSet<>();// 5. 日志记录启动信息if (logger.isDebugEnabled()) {logger.debug("Refreshing " + this);}
}
初始化属性源示例:
@Override
protected void initPropertySources() {// 为子类提供自定义属性源的机会ConfigurableEnvironment env = getEnvironment();if (env instanceof ConfigurableWebEnvironment) {((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, null);}
}
🏗️ 阶段2:obtainFreshBeanFactory() - 获取BeanFactory
BeanFactory 创建与加载流程:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {// 1. 刷新BeanFactory(抽象方法,由子类实现)refreshBeanFactory();// 2. 获取刷新后的BeanFactoryConfigurableListableBeanFactory beanFactory = getBeanFactory();if (logger.isDebugEnabled()) {logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);}return beanFactory;
}
子类实现示例(GenericApplicationContext):
@Override
protected final void refreshBeanFactory() throws IllegalStateException {// 1. 如果已有BeanFactory,先销毁if (hasBeanFactory()) {destroyBeans();closeBeanFactory();}try {// 2. 创建新的BeanFactoryDefaultListableBeanFactory beanFactory = createBeanFactory();beanFactory.setSerializationId(getId());// 3. 定制BeanFactory(允许覆盖)customizeBeanFactory(beanFactory);// 4. 加载Bean定义loadBeanDefinitions(beanFactory);// 5. 设置BeanFactory引用this.beanFactory = beanFactory;} catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source", ex);}
}
⚙️ 阶段3:prepareBeanFactory() - 配置BeanFactory
BeanFactory 基础配置:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 1. 设置类加载器beanFactory.setBeanClassLoader(getClassLoader());beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory));beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// 2. 添加BeanPostProcessor(ApplicationContextAwareProcessor)beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));// 3. 忽略依赖接口(这些接口由ApplicationContext自动注入)beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);// 4. 注册可解析的依赖beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// 5. 添加ApplicationListener探测器beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// 6. 如果存在LoadTimeWeaver,则添加对应的BeanPostProcessorif (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}// 7. 注册环境Beanif (!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());}
}
⚙️ 三、BeanFactoryPostProcessor 与 BeanPostProcessor 初始化
🔄 BeanFactoryPostProcessor 调用流程
BeanFactory后处理器执行机制:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {// 1. 获取所有BeanFactoryPostProcessor并排序PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// 2. 清除元数据缓存(如果已设置临时类加载器)if (beanFactory.getTempClassLoader() == null) {beanFactory.clearMetadataCache();}
}
PostProcessorRegistrationDelegate 核心逻辑:
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {// 1. 调用BeanDefinitionRegistryPostProcessor(优先级最高)Set<String> processedBeans = new HashSet<>();if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();// 1.1 首先处理实现了PriorityOrdered的BeanDefinitionRegistryPostProcessorString[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);registryProcessors.add(pp);processedBeans.add(ppName);}}sortPostProcessors(registryProcessors, beanFactory);invokeBeanDefinitionRegistryPostProcessors(registryProcessors, registry);// 1.2 处理实现了Ordered的BeanDefinitionRegistryPostProcessorregistryProcessors.clear();for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);registryProcessors.add(pp);processedBeans.add(ppName);}}sortPostProcessors(registryProcessors, beanFactory);invokeBeanDefinitionRegistryPostProcessors(registryProcessors, registry);// 1.3 处理常规的BeanDefinitionRegistryPostProcessorregistryProcessors.clear();for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName)) {BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);registryProcessors.add(pp);processedBeans.add(ppName);}}sortPostProcessors(registryProcessors, beanFactory);invokeBeanDefinitionRegistryPostProcessors(registryProcessors, registry);// 2. 调用BeanFactoryPostProcessor(按优先级顺序)invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);// 2.1 处理实现了PriorityOrdered的BeanFactoryPostProcessorString[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {BeanFactoryPostProcessor pp = beanFactory.getBean(ppName, BeanFactoryPostProcessor.class);priorityOrderedPostProcessors.add(pp);processedBeans.add(ppName);}}sortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// 2.2 处理实现了Ordered的BeanFactoryPostProcessorList<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {BeanFactoryPostProcessor pp = beanFactory.getBean(ppName, BeanFactoryPostProcessor.class);orderedPostProcessors.add(pp);processedBeans.add(ppName);}}sortPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// 2.3 处理常规的BeanFactoryPostProcessorList<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName)) {BeanFactoryPostProcessor pp = beanFactory.getBean(ppName, BeanFactoryPostProcessor.class);nonOrderedPostProcessors.add(pp);processedBeans.add(ppName);}}invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);} else {// 非BeanDefinitionRegistry的直接调用invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}
}
🛠️ BeanPostProcessor 注册流程
Bean后处理器注册机制:
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
BeanPostProcessor 注册详细流程:
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {// 1. 获取所有BeanPostProcessor的Bean名称String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);// 2. 注册BeanPostProcessorChecker(用于日志记录)int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));// 3. 按优先级分类注册BeanPostProcessorList<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();// 3.1 分类处理for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);priorityOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);} else {nonOrderedPostProcessorNames.add(ppName);}}// 3.2 注册实现了PriorityOrdered的BeanPostProcessorsortPostProcessors(priorityOrderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// 3.3 注册实现了Ordered的BeanPostProcessorList<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();for (String ppName : orderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);orderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}sortPostProcessors(orderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, orderedPostProcessors);// 3.4 注册常规BeanPostProcessorList<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);// 3.5 重新注册内部BeanPostProcessor(确保在最后执行)sortPostProcessors(internalPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, internalPostProcessors);// 3.6 添加ApplicationListener探测器beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
📢 四、事件、多播、监听器注册阶段
🔊 事件系统初始化流程
消息源初始化:
protected void initMessageSource() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();// 1. 检查是否已存在MessageSource Beanif (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);// 设置父MessageSource以支持嵌套解析if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;if (hms.getParentMessageSource() == null) {hms.setParentMessageSource(getInternalParentMessageSource());}}if (logger.isDebugEnabled()) {logger.debug("Using MessageSource [" + this.messageSource + "]");}} else {// 2. 创建默认的DelegatingMessageSourceDelegatingMessageSource dms = new DelegatingMessageSource();dms.setParentMessageSource(getInternalParentMessageSource());this.messageSource = dms;beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);if (logger.isDebugEnabled()) {logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME + "': using default [" + this.messageSource + "]");}}
}
事件广播器初始化:
protected void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();// 1. 检查是否已存在ApplicationEventMulticaster Beanif (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);if (logger.isDebugEnabled()) {logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");}} else {// 2. 创建默认的SimpleApplicationEventMulticasterthis.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);if (logger.isDebugEnabled()) {logger.debug("Unable to locate ApplicationEventMulticaster with name '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "': using default [" + this.applicationEventMulticaster + "]");}}
}
👂 监听器注册机制
事件监听器注册流程:
protected void registerListeners() {// 1. 注册静态指定的监听器for (ApplicationListener<?> listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);}// 2. 从BeanFactory中检测并注册监听器BeanString[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);for (String listenerBeanName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);}// 3. 发布早期事件(如果有)Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;this.earlyApplicationEvents = null;if (earlyEventsToProcess != null) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);}}
}
🎯 子类扩展点:onRefresh()
模板方法供子类扩展:
protected void onRefresh() throws BeansException {// 空实现,子类可以重写此方法以添加特定的初始化逻辑// 例如:初始化特定于Web的Bean、启动定时任务等
}
Web应用上下文中的实现示例:
@Override
protected void onRefresh() {// 调用父类实现super.onRefresh();try {// 初始化主题功能initThemeSource();// 初始化Servlet(如果是Web应用)initServlets();} catch (BeansException ex) {throw ex;} catch (Exception ex) {throw new ApplicationContextException("Failed to initialize context", ex);}
}
🔍 五、源码路径追踪:AbstractApplicationContext
📊 refresh() 方法执行流程图
完整的刷新流程可视化:
🔎 关键阶段源码深度分析
finishBeanFactoryInitialization() - 单例预实例化:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// 1. 初始化转换服务(用于类型转换)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. 注册默认的字符串解析器if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));}// 3. 初始化LoadTimeWeaver(AOP相关)String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}// 4. 停止使用临时类加载器beanFactory.setTempClassLoader(null);// 5. 冻结所有Bean定义(不允许修改)beanFactory.freezeConfiguration();// 6. 急切地实例化所有非懒加载单例BeanbeanFactory.preInstantiateSingletons();
}
finishRefresh() - 完成刷新:
protected void finishRefresh() {// 1. 清除上下文级别的资源缓存clearResourceCaches();// 2. 初始化LifecycleProcessorinitLifecycleProcessor();// 3. 启动LifecycleProcessor(触发Lifecycle Bean的启动)getLifecycleProcessor().onRefresh();// 4. 发布ContextRefreshedEvent事件publishEvent(new ContextRefreshedEvent(this));// 5. 参与LiveBeansView(如果启用)LiveBeansView.registerApplicationContext(this);
}
🐛 六、调试日志与启动问题排查
📝 启动日志输出示例
完整的容器启动日志序列:
2024-01-15 10:30:15.123 INFO - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1a2b3c4d
2024-01-15 10:30:15.124 DEBUG - Bean factory for AnnotationConfigApplicationContext: org.springframework.beans.factory.support.DefaultListableBeanFactory@5d6e7f82024-01-15 10:30:15.125 INFO - Registering annotated classes: [com.example.AppConfig]
2024-01-15 10:30:15.126 DEBUG - Registered annotated class: com.example.AppConfig2024-01-15 10:30:15.127 INFO - Overriding bean definition for bean 'userService' with a different definition
2024-01-15 10:30:15.128 DEBUG - Processing injected element of bean 'userService': AutowiredFieldElement for private UserRepository com.example.UserService.userRepository2024-01-15 10:30:15.129 INFO - Creating shared instance of singleton bean 'userService'
2024-01-15 10:30:15.130 DEBUG - Creating instance of bean 'userService'
2024-01-15 10:30:15.131 DEBUG - Eagerly caching bean 'userService' to allow for resolving potential circular references2024-01-15 10:30:15.132 INFO - Bean 'userService' of type [com.example.UserService] is not eligible for getting processed by all BeanPostProcessors
2024-01-15 10:30:15.133 DEBUG - Finished creating instance of bean 'userService'2024-01-15 10:30:15.134 INFO - Publishing event in context: org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@1a2b3c4d]
2024-01-15 10:30:15.135 INFO - Started ApplicationContext in 0.012 seconds (JVM running for 15.678)
🔧 调试技巧与工具
启动过程调试配置:
@Configuration
@Slf4j
public class StartupDebugConfig {/*** 启动过程监控Bean*/@Beanpublic StartupMonitor startupMonitor() {return new StartupMonitor();}/*** 自定义Bean后处理器用于调试*/@Beanpublic static BeanPostProcessor debugBeanPostProcessor() {return new DebugBeanPostProcessor();}
}/*** 启动监控器*/
@Component
@Slf4j
public class StartupMonitor implements ApplicationListener<ContextRefreshedEvent> {@Autowiredprivate ConfigurableApplicationContext context;@PostConstructpublic void init() {log.info("=== Spring容器启动监控器已初始化 ===");}@Overridepublic void onApplicationEvent(ContextRefreshedEvent event) {if (event.getApplicationContext() == context) {log.info("=== 容器启动完成,开始统计信息 ===");printBeanStatistics();printStartupTime();}}private void printBeanStatistics() {String[] beanNames = context.getBeanDefinitionNames();log.info("Bean定义总数: {}", beanNames.length);Map<String, Integer> beanTypeCount = new HashMap<>();for (String beanName : beanNames) {try {Object bean = context.getBean(beanName);String type = bean.getClass().getSimpleName();beanTypeCount.merge(type, 1, Integer::sum);} catch (Exception e) {// 忽略无法获取的Bean}}log.info("Bean类型分布: {}", beanTypeCount);}private void printStartupTime() {long startupDate = context.getStartupDate();long currentTime = System.currentTimeMillis();long duration = currentTime - startupDate;log.info("容器启动耗时: {}ms", duration);}
}/*** 调试用Bean后处理器*/
@Slf4j
public class DebugBeanPostProcessor implements BeanPostProcessor, Ordered {private final Set<String> processedBeans = ConcurrentHashMap.newKeySet();@Overridepublic int getOrder() {return Ordered.HIGHEST_PRECEDENCE;}@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (processedBeans.add(beanName)) {log.debug("Bean初始化前: {} [{}]", beanName, bean.getClass().getSimpleName());}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {log.debug("Bean初始化完成: {} [{}]", beanName, bean.getClass().getSimpleName());return bean;}
}
⚠️ 常见启动问题排查
循环依赖问题诊断:
@Component
public class CircularDependencyDetector {@Autowiredprivate ConfigurableListableBeanFactory beanFactory;public void detectCircularDependencies() {if (beanFactory instanceof DefaultListableBeanFactory) {DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;// 检查当前正在创建的BeanSet<String> beansInCreation = dlbf.getSingletonsCurrentlyInCreation();if (!beansInCreation.isEmpty()) {log.warn("当前正在创建的Bean: {}", beansInCreation);// 检查循环依赖for (String beanName : beansInCreation) {String[] dependentBeans = dlbf.getDependentBeans(beanName);String[] dependenciesForBean = dlbf.getDependenciesForBean(beanName);log.info("Bean '{}' 依赖的Bean: {}", beanName, Arrays.toString(dependenciesForBean));log.info("依赖 Bean '{}' 的Bean: {}", beanName, Arrays.toString(dependentBeans));}}}}
}
Bean定义冲突检测:
@Component
public class BeanDefinitionConflictDetector {@Autowiredprivate ConfigurableListableBeanFactory beanFactory;public void detectConflicts() {if (beanFactory instanceof DefaultListableBeanFactory) {DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;String[] beanNames = dlbf.getBeanDefinitionNames();Map<String, List<String>> typeToBeanNames = new HashMap<>();for (String beanName : beanNames) {BeanDefinition bd = dlbf.getBeanDefinition(beanName);String beanClassName = bd.getBeanClassName();if (beanClassName != null) {typeToBeanNames.computeIfAbsent(beanClassName, k -> new ArrayList<>()).add(beanName);}}// 报告冲突for (Map.Entry<String, List<String>> entry : typeToBeanNames.entrySet()) {if (entry.getValue().size() > 1) {log.warn("类型冲突: {} 被多个Bean定义使用: {}", entry.getKey(), entry.getValue());}}}}
}
💎 七、总结:Spring 容器的启动脉络
🎯 核心启动流程总结
Spring 容器刷新12个关键阶段:
| 阶段 | 方法 | 框架职责 | 核心动作 / 输出 | 业务扩展点 |
|---|---|---|---|---|
| ① | prepareRefresh() | 容器预处理阶段 | 初始化环境属性源、校验必要配置、准备事件系统 | 可重写以自定义环境加载逻辑(如动态配置中心) |
| ② | obtainFreshBeanFactory() | BeanFactory 创建 | 解析配置源(XML/注解),加载 BeanDefinition | 自定义 BeanDefinitionReader |
| ③ | prepareBeanFactory() | BeanFactory 初始化 | 注册类加载器、环境 Bean、依赖注入基础设施 | 可注册自定义 Aware 接口或依赖注入策略 |
| ④ | postProcessBeanFactory() | 工厂后处理入口 | 留给子类定制(如 Web 容器增加 Theme、ServletContext) | 常用于框架级容器扩展 |
| ⑤ | invokeBeanFactoryPostProcessors() | 处理 BeanDefinition | 调用所有 BeanFactoryPostProcessor(含 ConfigurationClassPostProcessor) | 扫描 @Configuration、@Bean、@Component 等配置 |
| ⑥ | registerBeanPostProcessors() | Bean 生命周期拦截器注册 | 注册 BeanPostProcessor,用于 Bean 实例化前后增强 | AOP、@Autowired、@Async 均依赖此机制 |
| ⑦ | initMessageSource() | 国际化支持 | 初始化 MessageSource,用于 i18n 文本解析 | 可替换为企业自定义多语言源 |
| ⑧ | initApplicationEventMulticaster() | 事件广播机制 | 初始化事件多播器(ApplicationEventMulticaster) | 支持事件驱动架构 |
| ⑨ | onRefresh() | 模板方法扩展 | 留给子类(如 Web、Cloud)实现特定初始化 | WebServer 启动点、Netty 初始化等 |
| ⑩ | registerListeners() | 注册事件监听器 | 注册所有 ApplicationListener,并广播早期事件 | 自定义事件系统可在此扩展 |
| ⑪ | finishBeanFactoryInitialization() | Bean 实例化阶段 | 实例化所有非懒加载单例,触发依赖注入、初始化回调 | BeanPostProcessor 开始工作 |
| ⑫ | finishRefresh() | 容器启动完成 | 发布 ContextRefreshedEvent,启动 Lifecycle Bean | Spring Boot 启动事件源(ApplicationReadyEvent) |
🚀 性能优化建议
容器启动性能调优策略:
@Configuration
@Slf4j
public class StartupOptimizationConfig {/*** 1. 合理使用懒加载*/@Bean@Lazypublic HeavyResourceService heavyResourceService() {return new HeavyResourceService(); // 延迟初始化}/*** 2. 避免不必要的组件扫描*/@ComponentScan(basePackages = "com.example.core", // 精确指定包路径excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*Test.*") // 排除测试类)public static class OptimizedScan {}/*** 3. 使用配置类索引加速扫描*/@Indexed@Configurationpublic static class IndexedConfig {// 编译时生成索引,加速组件扫描}/*** 4. 合理配置Bean作用域*/@Bean@Scope("prototype") // 原型作用域,避免不必要的单例初始化public StatefulService statefulService() {return new StatefulService();}
}
🔮 高级特性与最佳实践
容器启动事件监听:
@Component
@Slf4j
public class ComprehensiveStartupListener implements ApplicationContextAware, ApplicationListener<ApplicationEvent>, Ordered {private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;log.info("ApplicationContext已设置: {}", applicationContext.getClass().getSimpleName());}@Overridepublic void onApplicationEvent(ApplicationEvent event) {// 监听各种启动事件if (event instanceof ContextRefreshedEvent) {log.info("✅ 容器刷新完成");performPostStartupActions();} else if (event instanceof ContextStartedEvent) {log.info("🚀 容器启动完成");} else if (event instanceof ContextStoppedEvent) {log.info("🛑 容器停止");} else if (event instanceof ContextClosedEvent) {log.info("🔚 容器关闭");}}private void performPostStartupActions() {// 启动后执行的任务log.info("执行启动后任务...");// 例如:初始化缓存、启动定时任务等initializeCaches();startScheduledTasks();}@Overridepublic int getOrder() {return Ordered.HIGHEST_PRECEDENCE;}
}
