Spring Boot启动原理总结

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 是实现自动配置的关键类,它通过以下步骤加载自动配置:

  1. META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 加载自动配置类
  2. 过滤掉不符合条件的配置类(通过 @Conditional 系列注解)

2. 自动配置条件判断

Spring Boot 使用一系列 @Conditional 注解来决定是否加载特定配置:

  • @ConditionalOnClass:类路径下存在指定类时生效
  • @ConditionalOnMissingClass:类路径下不存在指定类时生效
  • @ConditionalOnBean:容器中存在指定Bean时生效
  • @ConditionalOnMissingBean:容器中不存在指定Bean时生效
  • @ConditionalOnProperty:配置文件中存在指定属性时生效
  • @ConditionalOnResource:类路径下存在指定资源时生效
  • @ConditionalOnWebApplication:是Web应用时生效
  • @ConditionalOnNotWebApplication:不是Web应用时生效

四、SpringApplication 核心组件

1. ApplicationContextInitializer

ConfigurableApplicationContext 刷新之前对其进行自定义操作,可通过 spring.factoriesaddInitializers() 方法注册。

2. ApplicationListener

监听 Spring Boot 事件,常用事件包括:

  • ApplicationStartingEvent:应用启动时触发
  • ApplicationEnvironmentPreparedEvent:环境准备完成后触发
  • ApplicationPreparedEvent:上下文准备完成后触发
  • ApplicationStartedEvent:上下文刷新完成后触发
  • ApplicationReadyEvent:应用准备就绪后触发
  • ApplicationFailedEvent:启动失败时触发

3. Banner

启动时控制台打印的横幅,可通过 banner.txt 文件或 spring.banner.location 属性自定义。

五、内嵌服务器启动原理

对于Web应用,Spring Boot 会自动启动内嵌服务器(Tomcat、Jetty或Undertow):

  1. 当检测到类路径下有 servlet-api 相关依赖时,自动配置为Servlet Web应用
  2. 通过 ServletWebServerFactoryAutoConfiguration 自动配置服务器工厂
  3. refreshContext() 阶段创建并启动服务器

六、总结

Spring Boot 启动过程的核心可以概括为:

  1. 通过 SpringApplication 初始化应用
  2. 准备环境并发布相应事件
  3. 创建并配置应用上下文
  4. 执行自动配置(通过 @EnableAutoConfiguration
  5. 刷新应用上下文(执行Bean定义加载、依赖注入等)
  6. 启动内嵌服务器(Web应用)
  7. 执行 ApplicationRunnerCommandLineRunner

这种设计使得开发者只需关注业务代码,而无需手动配置大量的Spring基础设施,大大简化了Spring应用的开发流程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值