Spring Boot 启动原理详解
Spring Boot 的启动过程是一个精心设计的自动化配置流程,下面我将详细解析其核心原理。
一、启动入口
Spring Boot 应用的启动入口是包含 main() 方法的类,通常带有 @SpringBootApplication 注解:
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
二、启动过程详解
1. SpringApplication 初始化
SpringApplication.run() 方法内部会创建一个 SpringApplication 实例并调用其 run() 方法:
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return new SpringApplication(primarySource).run(args);
}
初始化过程包括以下关键步骤:
- 推断应用类型:根据类路径判断是 SERVLET 应用(Spring MVC)、REACTIVE 应用(WebFlux)还是普通应用
- 设置初始化器(Initializers):从 META-INF/spring.factories 加载 ApplicationContextInitializer
- 设置监听器(Listeners):从 META-INF/spring.factories 加载 ApplicationListener
- 推断主配置类:根据 main() 方法所在的类推断主配置类
2. run() 方法执行流程
run() 方法是 Spring Boot 启动的核心,主要步骤如下:
(1) 准备阶段
public ConfigurableApplicationContext run(String... args) {
// 1. 创建 StopWatch 用于统计启动耗时
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// 2. 创建引导上下文(BootstrapContext)和可配置应用上下文
ConfigurableApplicationContext context = null;
configureHeadlessProperty();
// 3. 获取 SpringApplicationRunListeners
SpringApplicationRunListeners listeners = getRunListeners(args);
// 4. 发布 ApplicationStartingEvent 事件
listeners.starting(bootstrapContext, this.mainApplicationClass);
}
(2) 环境准备
try {
// 1. 准备环境
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
configureIgnoreBeanInfo(environment);
// 2. 打印 Banner
Banner printedBanner = printBanner(environment);
// 3. 根据应用类型创建应用上下文
context = createApplicationContext();
// 4. 准备应用上下文
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
// 5. 刷新上下文(核心步骤)
refreshContext(context);
// 6. 刷新后处理
afterRefresh(context, applicationArguments);
// 7. 停止计时器
stopWatch.stop();
// 8. 发布 ApplicationStartedEvent 事件
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
// 9. 执行 Runner 接口实现类
callRunners(context, applicationArguments);
}
(3) 异常处理
catch (Throwable ex) {
handleRunFailure(context, ex, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, null);
throw new IllegalStateException(ex);
}
return context;
三、自动配置原理
@SpringBootApplication 是一个复合注解,包含三个核心注解:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
// ...
}
1. @EnableAutoConfiguration 解析
这是自动配置的核心注解:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
// ...
}
AutoConfigurationImportSelector 是实现自动配置的关键类,它通过以下步骤加载自动配置:
- 从
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports加载自动配置类 - 过滤掉不符合条件的配置类(通过
@Conditional系列注解)
2. 自动配置条件判断
Spring Boot 使用一系列 @Conditional 注解来决定是否加载特定配置:
@ConditionalOnClass:类路径下存在指定类时生效@ConditionalOnMissingClass:类路径下不存在指定类时生效@ConditionalOnBean:容器中存在指定Bean时生效@ConditionalOnMissingBean:容器中不存在指定Bean时生效@ConditionalOnProperty:配置文件中存在指定属性时生效@ConditionalOnResource:类路径下存在指定资源时生效@ConditionalOnWebApplication:是Web应用时生效@ConditionalOnNotWebApplication:不是Web应用时生效
四、SpringApplication 核心组件
1. ApplicationContextInitializer
在 ConfigurableApplicationContext 刷新之前对其进行自定义操作,可通过 spring.factories 或 addInitializers() 方法注册。
2. ApplicationListener
监听 Spring Boot 事件,常用事件包括:
ApplicationStartingEvent:应用启动时触发ApplicationEnvironmentPreparedEvent:环境准备完成后触发ApplicationPreparedEvent:上下文准备完成后触发ApplicationStartedEvent:上下文刷新完成后触发ApplicationReadyEvent:应用准备就绪后触发ApplicationFailedEvent:启动失败时触发
3. Banner
启动时控制台打印的横幅,可通过 banner.txt 文件或 spring.banner.location 属性自定义。
五、内嵌服务器启动原理
对于Web应用,Spring Boot 会自动启动内嵌服务器(Tomcat、Jetty或Undertow):
- 当检测到类路径下有
servlet-api相关依赖时,自动配置为Servlet Web应用 - 通过
ServletWebServerFactoryAutoConfiguration自动配置服务器工厂 - 在
refreshContext()阶段创建并启动服务器
六、总结
Spring Boot 启动过程的核心可以概括为:
- 通过
SpringApplication初始化应用 - 准备环境并发布相应事件
- 创建并配置应用上下文
- 执行自动配置(通过
@EnableAutoConfiguration) - 刷新应用上下文(执行Bean定义加载、依赖注入等)
- 启动内嵌服务器(Web应用)
- 执行
ApplicationRunner和CommandLineRunner
这种设计使得开发者只需关注业务代码,而无需手动配置大量的Spring基础设施,大大简化了Spring应用的开发流程。
1万+

被折叠的 条评论
为什么被折叠?



