看源码太枯燥,我们学思维就好;细节不深究,框架只要搭起来,剩下的就是按部就班的填空了。
一、核心启动流程概览
二、详细执行链路分析
1. 入口:main()
方法
码友们肯定都知道,SpringBoot的启动,只需要依赖web,然后再写以一个如下的main启动方法,就可以搭建起一个web服务了。
聪明的码友如果想知道:在main运行的那一刻,SpringBoot框架到底做了哪些事情?可以看看SpringBoot 启动入口深度解析:main方法执行全流程
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args); // 启动入口
}
}
主类上需要添加@SpringBootApplication,不加就会报错
2. SpringApplication
初始化
// SpringApplication 构造方法核心逻辑
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();// 推断应用类型
// 加载扩展点
this.bootstrapRegistryInitializers = new ArrayList<>(
getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 加载Listener
this.mainApplicationClass = deduceMainApplicationClass();
}
关键步骤:
- 推断应用类型:检查类路径(Servlet/Reactive/None)
- 加载
spring.factories
:从META-INF/spring.factories
加载扩展点 - 初始化引导注册器:Spring Boot 3.0+ 新增
BootstrapRegistry
机制
3. 环境准备(Environment
)
// SpringApplication.run() → prepareEnvironment()
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
// 1. 创建环境实例
ConfigurableEnvironment environment = getOrCreateEnvironment();
// 2. 配置环境(命令行参数、Profile 等)
configureEnvironment(environment, applicationArguments.getSourceArgs());
// 3. 附加配置属性源(支持 Spring Boot 配置绑定)
ConfigurationPropertySources.attach(environment);
// 4. 发布 "环境准备完成" 事件(允许监听器修改环境)
listeners.environmentPrepared(bootstrapContext, environment);
// 5. 调整默认属性源位置(确保优先级正确)
DefaultPropertiesPropertySource.moveToEnd(environment);
// 6. 校验环境前缀属性(防止非法配置)
Assert.state(!environment.containsProperty("spring.main.environment-prefix"),
"Environment prefix cannot be set via properties.");
// 7. 将环境属性绑定到 SpringApplication 对象
bindToSpringApplication(environment);
// 8. 环境类型转换(非自定义环境时)
if (!this.isCustomEnvironment) {
EnvironmentConverter environmentConverter = new EnvironmentConverter(getClassLoader());
environment = environmentConverter.convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());
}
// 9. 重新附加配置属性源(确保转换后属性源正确)
ConfigurationPropertySources.attach(environment);
return environment;
}
执行顺序:
- 根据应用类型(Servlet/Reactive/None)创建对应的环境对象;如
StandardServletEnvironment
(Web应用) - 加载配置源(
application.properties
/application.yml
)(--spring.profiles.active 参数) - 发布
ApplicationEnvironmentPreparedEvent
- 触发
ConfigFileApplicationListener
加载配置文件 - 触发
LoggingApplicationListener
初始化日志系统
- 触发
4. 创建应用上下文(ApplicationContext
)
// SpringApplication.run() → createApplicationContext()
protected ConfigurableApplicationContext createApplicationContext() {
return this.applicationContextFactory.create(this.webApplicationType);
}
// 默认创建 AnnotationConfigServletWebServerApplicationContext(Web应用)
创建的应用上下文类型:
应用类型 | 上下文实现类 | 说明 |
---|---|---|
SERVLET | AnnotationConfigServletWebServerApplicationContext | 支持 Servlet Web 应用(Tomcat/Jetty),整合了 Web 服务器启动 |
REACTIVE | AnnotationConfigReactiveWebServerApplicationContext | 支持响应式 Web 应用(Netty/WebFlux),内置响应式服务器启动 |
NONE | AnnotationConfigApplicationContext | 标准非 Web 应用上下文,仅处理 Spring Bean 容器 |
applicationContextFactory
的来源- 默认使用
ApplicationContextFactory.DEFAULT
实现 - 可通过
SpringApplication.setApplicationContextFactory()
自定义
- 默认使用
webApplicationType
的确定
在SpringApplication
构造阶段通过以下方式确定:
this.webApplicationType = WebApplicationType.deduceFromClasspath();
根据类路径推断应用类型:
-
存在
DispatcherHandler
→REACTIVE
-
存在
Servlet
或ConfigurableWebApplicationContext
→SERVLET
-
其他 →
NONE
(普通 Java 应用)
- 工厂创建逻辑 (
ApplicationContextFactory.create()
)
5. 准备上下文(prepareContext()
)
private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
// 1. 设置环境到上下文
context.setEnvironment(environment);
// 2. 后处理应用上下文
postProcessApplicationContext(context);
// 3. 处理AOT生成的初始化器
addAotGeneratedInitializerIfNecessary(this.initializers);
// 4. 应用初始化器
applyInitializers(context);
// 5. 发布ContextPrepared事件
listeners.contextPrepared(context);
// 6. 关闭引导上下文并注册
bootstrapContext.close(context);
// 7. 记录启动信息
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// 8. 注册关键单例Bean
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
// 9. 配置BeanFactory策略
if (beanFactory instanceof AbstractAutowireCapableBeanFactory autowireCapableBeanFactory) {
// 设置循环引用策略
autowireCapableBeanFactory.setAllowCircularReferences(this.allowCircularReferences);
if (beanFactory instanceof DefaultListableBeanFactory listableBeanFactory) {
// 设置Bean定义覆盖策略
listableBeanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
}
// 10. 处理延迟初始化
if (this.lazyInitialization) {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
// 11. 添加属性源排序处理器
context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));
// 12. 加载主配置源
if (!AotDetector.useGeneratedArtifacts()) {
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
load(context, sources.toArray(new Object[0]));
}
// 13. 发布ContextLoaded事件
listeners.contextLoaded(context);
}
核心步骤:
- 上下文基础配置
- 设置环境对象(
context.setEnvironment(environment)
) - 执行上下文后处理(
postProcessApplicationContext
),如添加资源加载器 - 应用所有初始化器(
applyInitializers
),执行自定义初始化逻辑
- 设置环境对象(
- 事件通知与引导关闭
- 发布
ContextPreparedEvent
事件(listeners.contextPrepared
) - 关闭引导上下文(
bootstrapContext.close
),将引导阶段单例Bean迁移至主上下文
- 发布
- 关键Bean注册
- 注册启动参数Bean(
springApplicationArguments
) - 注册Banner打印对象(
springBootBanner
) - 配置BeanFactory策略(循环引用/Bean覆盖等)
- 注册启动参数Bean(
- 特殊处理
- 添加懒加载处理器(若启用全局懒加载)
- 添加属性源排序处理器(确保配置优先级)
- 加载主配置源(
getAllSources()
+load()
)
- 最终事件通知
- 发布
ContextLoadedEvent
事件(listeners.contextLoaded
),允许最终调整上下文
- 发布
6. 刷新上下文(refreshContext()
→ 核心!)
// AbstractApplicationContext.refresh()
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 阶段0: 刷新准备
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
this.prepareRefresh(); // 准备刷新上下文
// 阶段1: 获取新BeanFactory
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
// 阶段2: 配置BeanFactory
this.prepareBeanFactory(beanFactory);
try {
// 阶段3: 后处理BeanFactory
this.postProcessBeanFactory(beanFactory);
// 阶段4: 执行BeanFactory后处理器
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
this.invokeBeanFactoryPostProcessors(beanFactory); // 关键:加载配置类/配置属性
this.registerBeanPostProcessors(beanFactory); // 注册Bean后处理器
beanPostProcess.end();
// 阶段5: 初始化消息源
this.initMessageSource();
// 阶段6: 初始化事件广播器
this.initApplicationEventMulticaster();
// 阶段7: 扩展点:子类初始化特殊Bean
this.onRefresh(); // Spring Boot 在此启动Web服务器
// 阶段8: 注册监听器
this.registerListeners();
// 阶段9: 完成BeanFactory初始化
this.finishBeanFactoryInitialization(beanFactory); // 实例化所有非懒加载单例
// 阶段10: 完成刷新
this.finishRefresh(); // 发布ContextRefreshedEvent事件
} catch (BeansException ex) {
// 异常处理:销毁已创建Bean并取消刷新
this.destroyBeans();
this.cancelRefresh(ex);
throw ex;
} finally {
// 清理缓存
this.resetCommonCaches();
contextRefresh.end();
}
}
}
关键扩展点详解:
1. invokeBeanFactoryPostProcessors()
- 自动配置入口
this.invokeBeanFactoryPostProcessors(beanFactory);
扩展机制:
- 执行
ConfigurationClassPostProcessor
处理@Configuration
类 - Spring Boot 关键:触发
AutoConfigurationImportSelector
- 扫描
META-INF/spring.factories
加载自动配置类 - 执行条件注解过滤 (
@ConditionalOnClass
等) - 加载顺序控制:
@AutoConfigureOrder
,@AutoConfigureBefore/After
- 扫描
典型流程:
2. onRefresh()
- 内嵌服务器启动
protected void onRefresh() {
super.onRefresh();
createWebServer(); // Spring Boot 扩展
}
扩展实现:
ServletWebServerApplicationContext
中:
protected void onRefresh() {
super.onRefresh();
try {
createWebServer(); // 创建并启动Tomcat/Jetty/Undertow
} catch (Throwable ex) {...}
}
核心动作:
- 从
BeanFactory
获取ServletWebServerFactory
- 使用
factory.getWebServer()
创建服务器实例 - 绑定
server.port
等配置属性 - 注册
DispatcherServlet
(Servlet 环境) 或WebHandler
(响应式环境)
3. finishBeanFactoryInitialization()
- 单例初始化扩展
finishBeanFactoryInitialization(beanFactory);
Spring Boot 扩展点:
- 健康检查系统:
HealthEndpointAutoConfiguration
- **注册 **
HealthContributorRegistry
- 内置磁盘/数据源/JMS 等健康指示器
- **注册 **
- 配置属性绑定:
ConfigurationPropertiesBindingPostProcessor
- **处理 **
@ConfigurationProperties
注解 - 将环境属性绑定到 Bean 字段
- **处理 **
- 启动指标:
ApplicationStartup
实现- 记录 Bean 初始化耗时
- **跟踪 **
@Bean
方法执行
4. finishRefresh()
- 生命周期回调
protected void finishRefresh() {
// 1. 发布ContextRefreshedEvent
publishEvent(new ContextRefreshedEvent(this));
// 2. Spring Boot扩展:启动完成处理
LiveBeansView.registerApplicationContext(this);
}
7. 刷新后处理
// 扩展点
afterRefresh(context, applicationArguments);
Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
}
listeners.started(context, timeTakenToStartup);
callRunners(context, applicationArguments);
执行顺序:
- 发布
ApplicationStartedEvent
- 执行
ApplicationRunner
和CommandLineRunner
- 按
@Order
顺序执行
- 按
- 发布
ApplicationReadyEvent
三、Spring框架集成关键点
- 自动配置原理:
- 条件注解:
@ConditionalOnClass
、@ConditionalOnMissingBean
- 配置类:
spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
- 条件注解:
- Servlet容器启动:
ServletWebServerFactoryAutoConfiguration
→ 创建TomcatServletWebServerFactory
DispatcherServletAutoConfiguration
→ 注册DispatcherServlet
- 数据源与事务:
DataSourceAutoConfiguration
→ 创建DataSource
TransactionAutoConfiguration
→ 启用@Transactional
四、思维导图总结
版本说明:
- Spring Boot 3.5.0 使用 Spring 6.2.7
- 自动配置路径:
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
- 事件驱动模型:
ApplicationEvent
+ApplicationListener