Spring Boot 源码解析(四):IoC 容器初始化深度剖析
大家好,老 J。
前三期我们讲了启动流程、@SpringBootApplication 注解、自动配置原理。这一期进入 Spring 最核心、最复杂、面试最高频的部分——IoC 容器的初始化过程。
说白了,就是 refresh() 方法里面的 12 个步骤。
面试官问“Spring 启动过程”,如果你能把 refresh() 这 12 步讲清楚,基本就过关了。
一、refresh() 方法概览
refresh() 是 AbstractApplicationContext 中的核心方法,定义了 Spring 容器的初始化流程。
// AbstractApplicationContext.java@Overridepublicvoidrefresh()throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 1. 刷新前的准备工作 prepareRefresh();// 2. 获取 BeanFactoryConfigurableListableBeanFactorybeanFactory= obtainFreshBeanFactory();// 3. BeanFactory 的准备工作(设置类加载器、后置处理器等) prepareBeanFactory(beanFactory);// 4. 子类处理(Web 容器会在这里做扩展) postProcessBeanFactory(beanFactory);// 5. 调用 BeanFactory 后置处理器 invokeBeanFactoryPostProcessors(beanFactory);// 6. 注册 Bean 后置处理器 registerBeanPostProcessors(beanFactory);// 7. 初始化消息源(国际化) initMessageSource();// 8. 初始化事件广播器 initApplicationEventMulticaster();// 9. 子类初始化(Web 容器在这里启动 Tomcat) onRefresh();// 10. 注册监听器 registerListeners();// 11. 实例化所有非懒加载的单例 Bean(核心!) finishBeanFactoryInitialization(beanFactory);// 12. 完成刷新,发布 ContextRefreshedEvent 事件 finishRefresh(); }}
二、12 步逐层拆解
第 1 步:prepareRefresh()——刷新前的准备工作
protectedvoidprepareRefresh() {// 设置启动时间this.startupDate = System.currentTimeMillis();// 设置容器为活动状态this.closed.set(false);this.active.set(true);// 初始化属性源(占位方法,子类可覆盖) initPropertySources();// 校验必须存在的属性 getEnvironment().validateRequiredProperties();// 初始化早期事件监听器集合this.earlyApplicationEvents = newLinkedHashSet<>();}
作用: 设置容器状态、初始化环境、验证属性。
第 2 步:obtainFreshBeanFactory()——获取 BeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {// 刷新 BeanFactory(子类实现) refreshBeanFactory();// 返回 BeanFactoryreturn getBeanFactory();}
在 GenericApplicationContext 中的实现:
@OverrideprotectedfinalvoidrefreshBeanFactory()throws IllegalStateException {// 如果已有 BeanFactory,先销毁if (this.refreshed) {thrownewIllegalStateException("..."); }// 设置序列化 IDthis.beanFactory.setSerializationId(getId());this.refreshed = true;}
作用: 获取或创建 BeanFactory(DefaultListableBeanFactory)。
第 3 步:prepareBeanFactory()——准备 BeanFactory
protectedvoidprepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 设置类加载器 beanFactory.setBeanClassLoader(getClassLoader());// 设置表达式解析器(支持 SpEL) beanFactory.setBeanExpressionResolver(newStandardBeanExpressionResolver(...));// 设置属性编辑器注册器 beanFactory.addPropertyEditorRegistrar(newResourceEditorRegistrar(...));// 添加 BeanPostProcessor(ApplicationContextAware 处理) beanFactory.addBeanPostProcessor(newApplicationContextAwareProcessor(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);// 注册特殊类型 Bean 的自动装配 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this);// 注册早期 BeanPostProcessor beanFactory.addBeanPostProcessor(newApplicationListenerDetector(this));// 检测 LoadTimeWeaverif (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(newLoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(newContextTypeMatchClassLoader(...)); }// 注册环境相关单例 Beanif (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); }// ... 注册 systemProperties、systemEnvironment 等}
作用: 设置 BeanFactory 的基础设施,包括类加载器、表达式解析器、特殊类型注入等。
第 4 步:postProcessBeanFactory()——子类扩展
protectedvoidpostProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 空方法,子类覆盖}
Web 容器的实现(AnnotationConfigServletWebServerApplicationContext):
@OverrideprotectedvoidpostProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 添加 Web 相关的 BeanPostProcessor beanFactory.addBeanPostProcessor(newWebApplicationContextServletContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(ServletContextAware.class);// 注册 Web 相关单例if (this.servletContext != null) { beanFactory.registerResolvableDependency(ServletContext.class, this.servletContext); }}
第 5 步:invokeBeanFactoryPostProcessors()——执行 BeanFactory 后置处理器
这是非常重要的一步,负责执行所有 BeanFactoryPostProcessor。
protectedvoidinvokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {// 委托给 PostProcessorRegistrationDelegate 执行 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// 检测 LoadTimeWeaverif (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(newLoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(newContextTypeMatchClassLoader(...)); }}
核心执行逻辑:
BeanFactoryPostProcessor 执行顺序:1. 先执行 BeanDefinitionRegistryPostProcessor(可以注册 Bean 定义) ├── 优先执行实现了 PriorityOrdered 接口的 ├── 然后执行实现了 Ordered 接口的 └── 最后执行其他的2. 再执行普通的 BeanFactoryPostProcessor ├── 优先执行 PriorityOrdered ├── 然后执行 Ordered └── 最后执行其他的
典型应用:@ComponentScan、@Import、@Bean 的解析都是在这一步完成的。
第 6 步:registerBeanPostProcessors()——注册 Bean 后置处理器
protectedvoidregisterBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);}
作用: 注册 BeanPostProcessor,这些处理器会在 Bean 实例化前后执行。
执行顺序:
-
1. 先注册 PriorityOrdered类型的 -
2. 再注册 Ordered类型的 -
3. 最后注册普通的 -
4. 注册 MergedBeanDefinitionPostProcessor(特殊处理)
常见 BeanPostProcessor:
-
• AutowiredAnnotationBeanPostProcessor:处理@Autowired注入 -
• CommonAnnotationBeanPostProcessor:处理@Resource、@PostConstruct等 -
• ApplicationContextAwareProcessor:处理各种*Aware接口
第 7 步:initMessageSource()——初始化国际化
protectedvoidinitMessageSource() {ConfigurableListableBeanFactorybeanFactory= getBeanFactory();// 检查是否有自定义的 MessageSourceif (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);// ... } else {// 没有则创建一个空的 DelegatingMessageSourceDelegatingMessageSourcedms=newDelegatingMessageSource(); dms.setParentMessageSource(getInternalParentMessageSource());this.messageSource = dms; beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); }}
第 8 步:initApplicationEventMulticaster()——初始化事件广播器
protectedvoidinitApplicationEventMulticaster() {ConfigurableListableBeanFactorybeanFactory= getBeanFactory();// 检查是否有自定义的 ApplicationEventMulticasterif (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {this.applicationEventMulticaster = beanFactory.getBean( APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); } else {// 默认使用 SimpleApplicationEventMulticasterthis.applicationEventMulticaster = newSimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); }}
作用: 初始化事件广播器,用于 Spring 的事件机制。
第 9 步:onRefresh()——子类初始化(Web 容器启动点)
protectedvoidonRefresh()throws BeansException {// 空方法,子类覆盖}
Web 容器的实现(重要!Tomcat 在这里启动):
// ServletWebServerApplicationContext.onRefresh()@OverrideprotectedvoidonRefresh() {super.onRefresh();try { createWebServer(); // 创建并启动 Tomcat } catch (Throwable ex) {thrownewApplicationContextException("Unable to start web server", ex); }}privatevoidcreateWebServer() {WebServerFactoryfactory= getWebServerFactory();this.webServer = factory.getWebServer(getSelfInitializer());// Tomcat 在这里启动}
第 10 步:registerListeners()——注册监听器
protectedvoidregisterListeners() {// 注册静态指定的监听器for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); }// 注册容器中所有 ApplicationListener 类型的 Bean String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); }// 处理早期事件(refresh 之前发布的事件) Set<ApplicationEvent> earlyEvents = this.earlyApplicationEvents;this.earlyApplicationEvents = null;if (earlyEvents != null) {for (ApplicationEvent earlyEvent : earlyEvents) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } }}
第 11 步:finishBeanFactoryInitialization()——实例化单例 Bean(最核心!)
这一步是整个 refresh() 中最重要的步骤,负责实例化所有非懒加载的单例 Bean。
protectedvoidfinishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// 1. 初始化 ConversionService(类型转换服务)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 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); }// 4. 停止使用临时类加载器 beanFactory.setTempClassLoader(null);// 5. 冻结配置(所有 Bean 定义不再允许修改) beanFactory.freezeConfiguration();// 6. 实例化所有非懒加载的单例 Bean(核心!) beanFactory.preInstantiateSingletons();}
preInstantiateSingletons() 核心逻辑:
// DefaultListableBeanFactory.java@OverridepublicvoidpreInstantiateSingletons()throws BeansException {// 获取所有 Bean 名称 List<String> beanNames = newArrayList<>(this.beanDefinitionNames);for (String beanName : beanNames) {RootBeanDefinitionbd= getMergedLocalBeanDefinition(beanName);// 跳过抽象类、懒加载、多例if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {// 判断是否是 FactoryBeanif (isFactoryBean(beanName)) {// FactoryBean 的处理 FactoryBean<?> factory = getBean(FACTORY_BEAN_PREFIX + beanName, FactoryBean.class);if (factory.isEagerInit()) { getBean(beanName); } } else {// 普通 Bean,调用 getBean() 实例化 getBean(beanName); } } }// 触发 SmartInitializingSingleton 回调for (String beanName : beanNames) {ObjectsingletonInstance= getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) { ((SmartInitializingSingleton) singletonInstance).afterSingletonsInstantiated(); } }}
getBean() 的调用链:
getBean(beanName) ↓doGetBean(beanName, ...) ↓getSingleton(beanName) // 尝试从缓存获取 ↓ (如果没有)createBean(beanName, ...) ↓doCreateBean(beanName, ...) ↓createBeanInstance() // 实例化(调用构造器) ↓populateBean() // 属性填充(@Autowired 在这里完成) ↓initializeBean() // 初始化(@PostConstruct、init-method、AOP)
第 12 步:finishRefresh()——完成刷新
protectedvoidfinishRefresh() {// 1. 清除 ResourceLoader 缓存 clearResourceCaches();// 2. 初始化生命周期处理器 initLifecycleProcessor();// 3. 调用 LifecycleProcessor 的 onRefresh 方法 getLifecycleProcessor().onRefresh();// 4. 发布 ContextRefreshedEvent 事件 publishEvent(newContextRefreshedEvent(this));// 5. 注册 MBean(JMX) LiveBeansView.registerApplicationContext(this);}
三、一张图总结 refresh() 12 步
┌─────────────────────────────────┐ │ refresh() 启动 │ └────────────────┬────────────────┘ │ ┌────────────────▼────────────────┐ │ 1. prepareRefresh │ 准备刷新 └────────────────┬────────────────┘ │ ┌────────────────▼────────────────┐ │ 2. obtainFreshBeanFactory │ 获取 BeanFactory └────────────────┬────────────────┘ │ ┌────────────────▼────────────────┐ │ 3. prepareBeanFactory │ 准备 BeanFactory └────────────────┬────────────────┘ │ ┌────────────────▼────────────────┐ │ 4. postProcessBeanFactory │ 子类扩展 └────────────────┬────────────────┘ │ ┌────────────────▼────────────────┐ │ 5. invokeBeanFactoryPostProcessors│ 执行 BeanFactory 后置处理器 │ (解析 @ComponentScan、@Bean) │ └────────────────┬────────────────┘ │ ┌────────────────▼────────────────┐ │ 6. registerBeanPostProcessors │ 注册 Bean 后置处理器 └────────────────┬────────────────┘ │ ┌────────┬────────┬───────┴───────┬────────┬────────┐ ▼ ▼ ▼ ▼ ▼ ▼ 7.init 8.init 9.onRefresh 10.reg 11.实例化 12.finish Message Event (Tomcat启动) Listener Bean Refresh Source Broadcaster
四、面试回答模板
问:Spring 容器的启动过程是怎样的?
Spring 容器的启动核心是
refresh()方法,一共 12 个步骤:
1. prepareRefresh:设置容器状态,初始化环境变量 2. obtainFreshBeanFactory:获取或创建 BeanFactory 3. prepareBeanFactory:设置类加载器、表达式解析器等 4. postProcessBeanFactory:子类扩展,Web 容器会在这里添加扩展 5. invokeBeanFactoryPostProcessors:执行 BeanFactory 后置处理器, @ComponentScan、@Bean的解析在这里完成6. registerBeanPostProcessors:注册 Bean 后置处理器,如 @Autowired的处理
7. initMessageSource:初始化国际化 8. initApplicationEventMulticaster:初始化事件广播器 9. onRefresh:子类初始化,Web 容器在这里启动 Tomcat 10. registerListeners:注册事件监听器 11. finishBeanFactoryInitialization:实例化所有非懒加载的单例 Bean,这是最核心的一步 12. finishRefresh:完成刷新,发布 ContextRefreshedEvent
其中,第 5 步负责 Bean 定义的解析,第 6 步注册处理器,第 11 步真正实例化 Bean。
五、下期预告
Spring Boot 源码解析(五):Bean 的实例化与循环依赖解决
-
• getBean()的完整流程 -
• 三级缓存如何解决循环依赖 -
• @Autowired的工作原理 -
• 面试高频题:为什么 Spring 能解决循环依赖?
六、互动时间
refresh() 12 步,最让你头疼的是哪一步?
-
• 循环依赖的原理? -
• AOP 代理的创建时机? -
• FactoryBean 的处理?
评论区聊聊,老 J 给你解答。
我是老 J,下期见。
夜雨聆风