Spring Boot 启动流程及配置类解析原理

Spring Boot 是一个基于 Spring 框架的开源框架,旨在简化 Spring 应用的配置和部署。通过提供约定优于配置的原则,Spring Boot 大大降低了 Java 企业级应用的开发复杂度。本文将详细介绍 Spring Boot 的启动流程及其配置类的解析原理,帮助开发者深入理解 Spring Boot 的工作机制。

一、Spring Boot 启动流程

1.1 启动入口

Spring Boot 应用的启动入口通常是一个带有 main 方法的类,该类被注解为 @SpringBootApplication。该注解实际上是一个复合注解,包含了以下三个注解:

  • @Configuration:指示该类是一个 Spring 配置类。
  • @EnableAutoConfiguration:启用 Spring Boot 的自动配置机制。
  • @ComponentScan:启用组件扫描,以自动发现并注册 Spring 组件。

以下是一个简单的 Spring Boot 启动类示例:

复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}
​

1.2 SpringApplication 的启动过程

在 main 方法中,调用了 SpringApplication.run() 方法,该方法是 Spring Boot 应用启动的核心。其主要流程如下:

  1. 创建 SpringApplication 实例 :
    SpringApplication 是启动 Spring Boot 应用的核心类。它负责启动应用的上下文,并执行所有必要的初始化步骤。

    复制代码
    SpringApplication application = new SpringApplication(MyApplication.class);
    ​
  2. 准备上下文 :

    在 run 方法中,首先会准备一个 ApplicationContext(默认是 AnnotationConfigApplicationContext 或 WebApplicationContext),并将主类传入。

  3. 加载配置 :

    根据 @SpringBootApplication 中的设置,加载应用的配置文件(如 application.properties 或 application.yml),并将其转化为配置属性。

  4. 执行自动配置 :

    通过 @EnableAutoConfiguration 注解,Spring Boot 会自动装配必要的组件。例如,如果存在数据库驱动,则自动配置 DataSource。

  5. 启动应用上下文 :

    启动 ApplicationContext,完成 Bean 的初始化和依赖注入。

  6. 触发 ApplicationRunner 和 CommandLineRunner :

    如果定义了 ApplicationRunner 或 CommandLineRunner 接口的实现类,Spring Boot 会在应用启动后自动调用它们。

1.3 SpringApplication.run() 的关键步骤

以下是 SpringApplication.run() 方法中的关键步骤详细解析:

复制代码
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
    SpringApplication application = new SpringApplication(primarySource);
    return application.run(args);
}
​
  1. 构造 SpringApplication 实例 :
    primarySource 是启动类,用于加载上下文。
  2. 准备环境 :
    调用 prepareEnvironment() 方法,设置应用的环境(如 Environment 和 ApplicationArguments)。
  3. 创建应用上下文 :
    调用 createApplicationContext() 方法,根据应用类型创建相应的 ApplicationContext。
  4. 准备上下文 :
    调用 prepareContext() 方法,配置上下文的属性和 Bean。
  5. 刷新上下文 :
    调用 refreshContext() 方法,初始化和刷新上下文。
  6. 调用应用的生命周期事件 :
    触发 ApplicationStartedEvent 和 ApplicationReadyEvent 事件。

1.4 事件机制

在 Spring Boot 启动过程中,会触发多个事件,例如 ApplicationStartedEvent、ApplicationEnvironmentPreparedEvent 和 ApplicationReadyEvent。开发者可以通过实现 ApplicationListener 接口来监听这些事件。

二、Spring Boot 配置类解析原理

2.1 配置类的定义

在 Spring Boot 中,配置类通常是使用 @Configuration 注解标记的类。这些类用于定义 Bean,进行依赖注入和其他配置信息。以下是一个配置类的示例:

复制代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {
    @Bean
    public MyService myService() {
        return new MyService();
    }
}
​

2.2 配置类的解析过程

当 Spring Boot 启动时,配置类的解析过程主要涉及以下步骤:

  1. 组件扫描 :
    在 @SpringBootApplication 注解的类中,会进行组件扫描,寻找所有的 @Configuration 注解。
  2. 创建 ConfigurationClassParser 实例 :
    ConfigurationClassParser 是解析配置类的核心类,负责分析和处理所有的配置类。
  3. 解析配置类 :
    ConfigurationClassParser 会解析配置类中的 @Bean 方法,并生成相应的 BeanDefinition。
  4. 注册 BeanDefinition :
    将解析得到的 BeanDefinition 注册到 BeanDefinitionRegistry 中,供后续使用。

2.3 Bean 的创建与注入

当需要使用某个 Bean 时,Spring 容器会根据 BeanDefinition 创建 Bean 实例,并进行依赖注入。

  1. 获取 BeanDefinition :
    在调用 Bean 的时候,Spring 会从 ApplicationContext 中获取对应的 BeanDefinition。
  2. 实例化 Bean :
    使用 BeanFactory 中的 doGetBean() 方法,创建 Bean 实例。
  3. 依赖注入 :
    Spring 会自动识别 Bean 的依赖关系,进行依赖注入。

2.4 注解的作用

在配置类中,常用的注解包括:

  • @Bean:用于定义 Bean 方法,返回的对象将被注册为 Spring 的 Bean。
  • @Configuration:标识配置类,表示该类可以包含多个 @Bean 方法。
  • @Conditional:用于条件化 Bean 的创建,根据条件决定是否创建 Bean。
相关推荐
captain3763 小时前
MyBatis(入门5)其他查询操作
java·数据库·spring boot·mybatis
Novproxy_Z4 小时前
商用代理避坑:如何识别商家拿机房 IP 冒充住宅 IP
java·网络·tcp/ip
文丑颜不良啊5 小时前
LeetCode1481~1500题目解析
java·leetcode
2601_962885725 小时前
quotes 字段全解:涨跌幅、振幅、换手率的口径与单位
java·前端·spring
深蓝AI5 小时前
Python 3.13 的 Queue.shutdown:异步消费者终于能正常收工了
后端
前端精髓5 小时前
调用openrouter的免费API模型
java·前端·javascript
武子康5 小时前
MultiNet6 空闲崩溃:`EXCVADDR=0x8` 后又出现 `CORRUPT HEAP`
人工智能·后端·agent
步行cgn5 小时前
Spring MVC 拦截器 Interceptor 详解:从执行流程到实战应用
java·spring·mvc
文丑颜不良啊5 小时前
LeetCode1381~1400题目解析
java·leetcode
开开心心_Every6 小时前
快速隐藏程序工具自定义快捷键一键切换
java·开发语言·前端·spring·智能手机·word·intellij-idea