Spring Boot启动流程

启动流程

  1. 主方法

    应用程序从main方法开始,调用SpringApplication.run(),传入主类和命令行参数。
  2. 创建应用上下文

    SpringApplication通过createApplicationContext()方法根据应用类型创建ApplicationContext实例(通常是AnnotationConfigApplicationContextWebApplicationContext)。
  3. 设置上下文环境

    通过prepareEnvironment()方法配置Environment,加载系统属性、环境变量、配置文件等,确保环境在应用启动时可用。
  4. 加载配置

    load()方法根据配置类、配置文件(如application.propertiesapplication.yml)以及@PropertySource注解加载属性,准备应用配置。
  5. 注册Bean

    执行registerBean(),扫描@ComponentScan指定的包,查找并注册被@Component@Service@Repository@Controller等注解标记的类为Spring Bean。
  6. 处理条件注解

    使用@Conditional等注解进行条件判断,决定是否加载特定的Bean。这一过程涉及到ConditionEvaluator,它根据条件逻辑判断Bean的注册。
  7. 事件发布

    发布ApplicationEnvironmentPreparedEvent事件,允许监听器在上下文环境准备后进行配置。发布ApplicationPreparedEvent事件,表示上下文已准备好,但尚未刷新。
  8. 执行CommandLineRunner和ApplicationRunner

    在上下文刷新后,执行实现了CommandLineRunnerApplicationRunner接口的run方法,用于执行自定义的初始化逻辑。
  9. 启动Web服务器(如果是Web应用):

    对于Web应用,SpringApplication会创建并启动嵌入式Web服务器(如Tomcat、Jetty),调用WebServerFactory进行配置。
  10. 应用就绪

    最后发布ApplicationReadyEvent,标志着应用已完全启动,所有Bean均已初始化并可供使用。

结合Spring Boot的源码进行详细分析

1. 主方法

在Spring Boot应用的主类中,我们通常会看到如下代码:

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
  • SpringApplication.run()是启动的入口,实质上是调用了SpringApplication类的方法。

SpringApplication类是核心类之一,其构造函数如下:

public SpringApplication(Class<?>... primarySources) {
    this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
}
  • primarySources参数指定了主应用类,用于后续的上下文创建和Bean注册。

2. 创建应用上下文

SpringApplication.run()的实现:

public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
    return new SpringApplication(primarySource).run(args);
}
  • run(args)会创建ApplicationContext,通常是AnnotationConfigApplicationContextWebApplicationContext

3. 设置上下文环境

run()方法内部:

private ConfigurableApplicationContext run(String[] args) {
    ConfigurableApplicationContext context = createApplicationContext();
    prepareEnvironment(context.getEnvironment());
    context.refresh();
    return context;
}
  • prepareEnvironment(context.getEnvironment())加载系统属性、环境变量和配置文件(如application.properties)到Environment中。

4. 加载配置

prepareContext()方法中,会使用ApplicationConfigFileApplicationListener来处理配置文件:

protected void prepareContext(ConfigurableApplicationContext context, Environment environment) {
    context.setEnvironment(environment);
    // 处理配置文件
    new ApplicationConfigFileApplicationListener().onApplicationEvent(event);
}
  • ApplicationConfigFileApplicationListener会解析application.propertiesapplication.yml,并将其属性加载到环境中。

5. 注册Bean

refresh()方法会触发Bean注册:

public void refresh() {
    // 创建并注册所有Bean
    this.beanFactory = createBeanFactory();
    registerBeanDefinitions();
}
  • registerBeanDefinitions()会扫描被@Component@Service等注解标记的类,并注册为Spring Bean。

6. 处理条件注解

在Bean的注册过程中,Spring Boot会处理条件注解:

if (condition.matches(context, metadata)) {
    // 注册条件符合的Bean
}
  • ConditionEvaluator类会根据条件判断是否加载特定的Bean。

7. 事件发布

在上下文准备好后,Spring Boot会发布事件:

publishEvent(new ApplicationEnvironmentPreparedEvent(this, environment, args));
  • ApplicationPreparedEvent和其他事件允许开发者注册监听器进行响应。

8. 执行CommandLineRunner和ApplicationRunner

在上下文刷新后,执行实现了CommandLineRunnerApplicationRunner的Bean:

for (CommandLineRunner runner : getCommandLineRunners()) {
    runner.run(args);
}
  • 这允许开发者在应用启动后执行自定义逻辑。

9. 启动Web服务器

对于Web应用,Spring Boot会启动嵌入式Web服务器:

this.webServer = this.webServerFactory.getWebServer(this::onStartup);
  • WebServerFactory负责创建并启动如Tomcat、Jetty等服务器。

10. 应用就绪

最后,发布ApplicationReadyEvent

publishEvent(new ApplicationReadyEvent(this, args));
  • 这标志着应用完全启动,所有Bean均已初始化,可以接受请求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yymagicer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值