10个点介绍SpringBoot3工作流程与核心组件源码解析

Spring Boot 的重要性 V 哥就不多说了,在学习的过程中,如果我们只知道它用来简化 SSM 的开发,用用 API,那是万万不够的,V 哥的逻辑是,先会用,再深入,这个企业应用的重量级框架非常值得你好好深入研究,今天的文章,将会帮助你梳理 SpringBoot3的工作流程,核心组件分析等内容:

一、SpringBoot3工作流程

1. 启动阶段:

  • 当Spring Boot应用启动时,SpringApplication类会被实例化。这个类负责创建和配置应用上下文,并启动应用。

  • SpringApplicationRunListeners 被用来通知监听器在启动的不同阶段(如开始、环境准备、上下文初始化、应用启动完成)。

2. 环境配置:

  • SpringEnvironment 接口的实现类(如StandardEnvironment)被用来加载外部配置(application.properties 或 application.yml)和系统属性。

  • PropertySources 用于管理不同来源的配置属性。

3. 上下文初始化:

  • ApplicationContextInitializer 接口的实现类可以在这里介入,用于在上下文创建之前进行自定义初始化。

  • ConfigurableEnvironment 允许在上下文中添加额外的 PropertySource 或 BeanDefinition。

4. Bean定义加载:

  • BeanDefinitionRegistryPostProcessor 允许在所有的 BeanDefinition 加载完成后进行修改或添加新的 BeanDefinition。

  • @Configuration 注解的类被扫描并处理,这些类中的 @Bean 方法会被调用,生成相应的 BeanDefinition。

5. 依赖注入:

  • BeanFactory 或 ApplicationContext 用于实例化和组装 Bean,处理依赖注入。

  • @Autowired 和其他相关的注解(如 @Inject)被处理,以实现依赖注入。

6. 后处理:

  • BeanPostProcessor 允许在 Bean 初始化前后进行额外的处理。

  • @PostConstruct 注解的方法会在 Bean 初始化完成后执行。

7. 启动完成:

  • 所有的 Bean 都已经被加载和初始化,ApplicationRunner 和 CommandLineRunner 接口的实现类会被执行。

  • 应用完全启动,可以处理请求。

二、相关核心类源码分析

以下是一些核心类的简化源码示例和解释:

1.SpringApplication

SpringApplication是Spring Boot应用程序的入口点:

public class SpringApplication extends SpringBootServletInitializer {
    private ConfigurableEnvironment environment = new StandardEnvironment();
    private SpringApplicationRunListeners listeners = new SpringApplicationRunListeners();

    public static ConfigurableApplicationContext run(Class<?>... primarySources) {
        return new SpringApplication(primarySources).run();
    }

    // ... 其他方法
}
  • SpringApplication 是启动Spring Boot应用的主类,它封装了应用的启动流程。

  • 它初始化环境、监听器,并负责创建和刷新应用上下文。

SpringApplication 逻辑过程

实例化 SpringApplication:

public static ConfigurableApplicationContext run(Class<?>... primarySources) {
    return new SpringApplication(primarySources).run();
}
  • 这是SpringApplication的静态工厂方法,用于创建一个新的SpringApplication实例,并传入主要的应用程序类(primarySources)。

  • 这个方法最终会调用run方法来启动应用程序。

配置环境:

Environment prepareEnvironment(MutablePropertySources propertySources, ConfigurableEnvironment environment) {
    // 配置环境变量、系统属性等
}
  • 在启动过程中,prepareEnvironment方法会被调用,用于准备应用程序的环境,包括加载系统属性和环境变量。

设置监听器:

SpringApplicationRunListeners listeners = new SpringApplicationRunListeners();
listeners.starting();
  • SpringApplicationRunListeners用于在应用程序的不同生命周期阶段发布事件。

  • 在启动时,会通知所有注册的监听器应用程序即将启动。

加载应用程序上下文:

ConfigurableApplicationContext createApplicationContext() {
    // 创建并配置ApplicationContext
}
  • createApplicationContext方法负责创建应用程序上下文(ApplicationContext),这是Spring容器的核心。

  • 上下文会被配置为使用SpringApplication中定义的属性源和其他配置。

刷新上下文:

void refresh(ContextRefreshScope refreshScope) {
    // 刷新ApplicationContext
}
  • refresh方法用于刷新上下文,这包括注册Bean后处理器、初始化所有的Bean以及触发Bean的生命周期回调。

运行应用程序:

public ConfigurableApplicationContext run() {
    // 启动应用程序
}
  • run方法是启动Spring Boot应用程序的核心方法。

  • 它首先调用prepareEnvironment,然后创建和刷新上下文,最后调用listeners.started()通知监听器应用程序已启动。

调用 CommandLineRunner 和 ApplicationRunner:

private void callRunners(ApplicationContext context, ApplicationArguments args) {
    // 调用Runner接口的实现
}
  • 在上下文刷新后,callRunners方法会被调用,用于执行实现了CommandLineRunner或ApplicationRunner接口的组件。

关闭应用程序:

public void stop() {
    // 关闭应用程序
}
  • stop方法用于优雅地关闭应用程序,它会通知监听器应用程序即将关闭,并关闭上下文。

SpringApplication类是Spring Boot应用程序的启动类,它负责整个应用程序的启动流程。从创建环境、配置资源、初始化Spring容器,到调用启动后的回调,SpringApplication提供了一个简单而强大的方式来管理Spring Boot应用程序的生命周期。通过理解SpringApplication的工作原理,开发者可以更好地控制和定制Spring Boot应用程序的行为。

2.ApplicationContextInitializer

ApplicationContextInitializer 是 Spring Boot 中的一个接口,它允许开发者在 Spring 应用上下文初始化之前进行自定义的初始化操作。这个接口对于执行一些预启动任务非常有用,比如添加额外的 BeanDefinition、设置特定的环境属性、或者注册自定义的 BeanFactoryPostProcessor。

ApplicationContextInitializer 接口定义

public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {
    void initialize(C applicationContext);
}

逻辑过程和源码分析

实现 ApplicationContextInitializer 接口:

开发者需要创建一个类实现 ApplicationContextInitializer 接口,并实现 initialize 方法。在这个方法中,可以对传入的 applicationContext 进行操作,比如添加 BeanDefinition 或者修改环境配置。

public class MyCustomApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        // 在这里可以对 applicationContext 进行操作
    }
}

注册 ApplicationContextInitializer:

在 Spring Boot 应用启动时,SpringApplication 类会查找所有的 ApplicationContextInitializer 实现,并注册它们。这通常通过 SpringFactoriesLoader 类来完成,它会加载 META-INF/spring.factories 文件中指定的 ApplicationContextInitializer 实现。

private static List<ApplicationContextInitializer<?>> getInitializers(Class<?>... types) {
    List<ApplicationContextInitializer<?>> initializers = new ArrayList<>();
    // 从 spring.factories 加载 ApplicationContextInitializer 实现
    for (Class<?> type : types) {
        String[] initializers = SpringFactoriesLoader.loadFactoryNames(type, ApplicationContextInitializer.class.getClassLoader());
        for (String initializer : initializers) {
            try {
                initializers.add((ApplicationContextInitializer) Class.forName(initializer).newInstance());
            } catch (Exception ex) {
                throw new IllegalArgumentException("Cannot instantiate ApplicationContextInitializer", ex);
            }
        }
    }
    return initializers;
}

执行 ApplicationContextInitializer:

当 Spring 应用上下文创建并准备好初始化时,SpringApplication 会遍历所有注册的 ApplicationContextInitializer 实现,并调用它们的 initialize 方法。

private void prepareContext(ConfigurableApplicationContext context, SpringApplicationRunListeners listeners) {
    // ... 其他初始化代码 ...
    getInitializers(context).forEach(initializer -> initializer.initialize(context));
    // ... 其他初始化代码 ...
}

在 prepareContext 方法中,getInitializers 方法会获取所有可用的 ApplicationContextInitializer 实现,并通过 forEach 循环依次调用它们的 initialize 方法。

自定义初始化逻辑:

在 initialize 方法中,开发者可以添加自定义的 BeanDefinition,或者修改 Environment 对象中的属性。这些更改将在后续的上下文刷新过程中生效。

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        BeanDefinitionRegistry regis

相关推荐

  1. 10介绍SpringBoot3工作流程核心组件

    2024-03-30 23:42:07       21 阅读
  2. SpringBoot

    2024-03-30 23:42:07       41 阅读
  3. OpenXR API概览核心组件

    2024-03-30 23:42:07       14 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-30 23:42:07       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-30 23:42:07       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-30 23:42:07       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-30 23:42:07       18 阅读

热门阅读

  1. 动态内存管理

    2024-03-30 23:42:07       20 阅读
  2. Spring Cache 快速入门

    2024-03-30 23:42:07       17 阅读
  3. docker 打包前台程序

    2024-03-30 23:42:07       16 阅读
  4. visual studio快捷键

    2024-03-30 23:42:07       18 阅读
  5. Android TV 4K UI

    2024-03-30 23:42:07       15 阅读
  6. Mysql中的那些锁

    2024-03-30 23:42:07       19 阅读
  7. axios请求类型是文件流怎么显示报错信息

    2024-03-30 23:42:07       14 阅读
  8. UI 神器 - Vue3 中如何使用 element-plus

    2024-03-30 23:42:07       18 阅读