深入理解 Spring Boot 启动原理

本文将从以下几个方面进行详细阐述:

  1. Spring Boot 启动过程概述
  2. BeanFactory 初始化
  3. Bean 的实例化和依赖注入
  4. Aware 接口的设置
  5. Bean 的初始化
  6. 单例 Bean 的后处理
  7. Spring 启动后的后处理
  8. 启动 HTTP 流量入口

一、Spring Boot 启动过程概述

Spring Boot 的启动过程可以分为几个主要阶段,从启动类开始,经过一系列的初始化和配置过程,最终启动 HTTP 服务器并准备好处理请求。

1.1 启动类

每一个 Spring Boot 应用程序都有一个主类,这个类包含了 main 方法,通常使用 @SpringBootApplication 注解标记。@SpringBootApplication 是一个组合注解,包含了 @Configuration, @EnableAutoConfiguration, 和 @ComponentScan

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

SpringApplication.run 方法启动了整个 Spring Boot 应用程序,触发了一系列的自动配置和初始化过程。

1.2 SpringApplication 初始化

SpringApplication 类负责引导和启动 Spring 应用程序。它的 run 方法完成了以下几件事情:

  • 创建并配置 ApplicationContext
  • 准备环境变量。
  • 加载所有的 ApplicationListener
  • 启动并刷新 ApplicationContext
  • 执行所有的 ApplicationRunnerCommandLineRunner
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
    return new SpringApplication(primarySource).run(args);
}

1.3 应用上下文的创建和刷新

ApplicationContext 是 Spring 框架中的核心容器。Spring Boot 使用不同的 ApplicationContext 实现来处理不同类型的应用程序(如 AnnotationConfigServletWebServerApplicationContext 用于 Web 应用程序)。上下文的刷新包含了所有 Bean 的创建和初始化过程,这也是我们将深入探讨的部分。

二、BeanFactory 初始化

在 Spring 中,BeanFactory 是最基本的容器接口,负责管理 Bean 的创建、配置和生命周期。Spring Boot 在启动过程中,会首先初始化 BeanFactory,并通过 BeanFactoryPostProcessor 对其进行配置和处理。

2.1 BeanFactoryPostProcessor

BeanFactoryPostProcessor 是在 BeanFactory 标准初始化之后执行的,用于对 BeanFactory 进行定制和修改。典型的 BeanFactoryPostProcessor 包括 PropertyPlaceholderConfigurerCustomEditorConfigurer

public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

BeanFactoryPostProcessor 在所有 Bean 被实例化之前执行,这使得它们可以用来修改 Bean 定义或添加一些自定义的初始化逻辑。

三、Bean 的实例化和依赖注入

BeanFactory 初始化完成后,Spring 开始实例化各个 Bean 并进行依赖注入。这一过程涉及到以下几个重要步骤:

3.1 Bean 实例化

Spring 通过反射机制来实例化 Bean。对于每个定义的 Bean,Spring 都会调用其默认构造函数或指定的构造函数来创建 Bean 实例。

TestSpringOrder order = new TestSpringOrder();

3.2 依赖注入

依赖注入是 Spring 核心功能之一,通过 @Autowired 注解可以自动注入依赖的 Bean。Spring 使用 AutowiredAnnotationBeanPostProcessor 处理这些注解,并注入相应的依赖。

@Autowired
private SomeService someService;

AutowiredAnnotationBeanPostProcessor 会在 Bean 实例化后对其进行扫描,找到所有的 @Autowired 字段,并注入相应的依赖。

四、Aware 接口的设置

Spring 提供了一系列的 Aware 接口,用于让 Bean 获得 Spring 容器的一些资源。实现这些接口的 Bean 在初始化时会被注入相应的资源。

4.1 常见的 Aware 接口

  • BeanNameAware: 提供 Bean 的名称。
  • BeanFactoryAware: 提供 BeanFactory 实例。
  • ApplicationContextAware: 提供 ApplicationContext 实例。
  • EnvironmentAware: 提供 Environment 实例。
  • ResourceLoaderAware: 提供 ResourceLoader 实例。
public class MyBean implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
}

4.2 Aware 设置过程

Spring 在初始化 Bean 时,会检查 Bean 是否实现了任何 Aware 接口,如果是,则调用相应的设置方法注入资源。例如,对于 ApplicationContextAware,Spring 会调用其 setApplicationContext 方法,将 ApplicationContext 注入到该 Bean 中。

五、Bean 的初始化

在完成实例化和依赖注入后,Spring 开始初始化 Bean,这一过程包括执行初始化方法和初始化回调。

5.1 BeanPostProcessor

BeanPostProcessor 是一个扩展点,允许在 Bean 初始化前后进行一些自定义处理。Spring 在 Bean 初始化之前和之后分别调用 postProcessBeforeInitializationpostProcessAfterInitialization 方法。

public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

5.2 @PostConstruct 和 InitializingBean

Spring 提供了两种方式来定义 Bean 的初始化方法:

  • 使用 @PostConstruct 注解标记初始化方法。
  • 实现 InitializingBean 接口并重写 afterPropertiesSet 方法。
@PostConstruct
public void init() {
    // initialization logic
}

@Override
public void afterPropertiesSet() throws Exception {
    // initialization logic
}

5.3 自定义初始化方法

除了 @PostConstructInitializingBean 之外,Spring 还允许在 Bean 定义中指定自定义的初始化方法。

@Bean(initMethod = "customInit")
public MyBean myBean() {
    return new MyBean();
}

六、单例 Bean 的后处理

在所有单例 Bean 初始化完成后,Spring 进行一些额外的处理,包括触发事件和执行一些特殊的回调。

6.1 SmartInitializingSingleton

SmartInitializingSingleton 是 Spring 3.1 引入的一个接口,用于在所有单例 Bean 初始化完成后执行一些逻辑。

public interface SmartInitializingSingleton {
    void afterSingletonsInstantiated();
}

6.2 事件监听

Spring 提供了丰富的事件机制,允许在应用程序不同阶段发布和监听事件。单例 Bean 初始化完成后,Spring 会发布 ContextRefreshedEvent

@Component
public class MyListener implements ApplicationListener<ContextRefreshedEvent> {
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        // handle event
    }
}

七、Spring 启动后的后处理

在应用程序上下文刷新完成后,Spring 还会进行一些额外的处理,如启动定时任务和发布其他应用事件。

7.1 SmartLifecycle

SmartLifecycle 是一个更高级的生命周期接口,允许在应用程序上下文刷新完成后执行一些操作,如启动后台任务。

public interface SmartLifecycle extends Lifecycle, Phased {
    boolean isAutoStartup();
    void stop(Runnable callback);
}

7.2 定时任务

Spring 通过 @Scheduled 注解支持定时任务。在应用程序上下文刷新完成后,所有标记了 @Scheduled 的方法都会按指定的计划执行。

@Scheduled(fixedRate = 5000)
public void scheduledTask() {
    // task logic
}

7.3 发布事件

Spring 在启动过程中会发布一系列事件,允许开发人员在特定的时机执行一些自定义逻辑。例如,在上下文刷新完成后,Spring 会发布 ContextRefreshedEvent

八、启动 HTTP 流量入口

Spring Boot 默认集成了嵌入式的 Tomcat 服务器,允许开发人员无需额外配置即可启动一个 Web 应用程序。

8.1 初始化 Spring MVC

在应用程序启动过程中,Spring Boot

会自动配置 Spring MVC 并初始化 DispatcherServlet

@Bean
public DispatcherServlet dispatcherServlet() {
    return new DispatcherServlet();
}

8.2 启动嵌入式服务器

Spring Boot 支持多种嵌入式服务器,如 Tomcat、Jetty 和 Undertow。在应用程序启动过程中,Spring Boot 会自动启动嵌入式服务器并监听指定端口。

@Bean
public ServletWebServerFactory servletWebServerFactory() {
    return new TomcatServletWebServerFactory();
}

8.3 CommandLineRunner

CommandLineRunner 接口允许在应用程序启动完成后执行一些自定义逻辑。所有实现 CommandLineRunner 接口的 Bean 会在应用程序启动后被调用。

@Component
public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        // custom logic
    }
}

结语

通过以上几个方面的详细探讨,我们可以看到 Spring Boot 的启动过程是如何一步步进行的。从初始化 BeanFactory,到实例化和初始化各个 Bean,再到处理单例 Bean 的后续工作,最后启动 HTTP 服务器并准备处理请求。理解这些过程可以帮助我们更好地使用 Spring Boot 进行开发,并在遇到问题时能够快速定位和解决问题。

Spring Boot 的设计理念就是简化开发人员的工作,使得复杂的配置和初始化过程对开发人员透明。这种设计不仅提高了开发效率,也使得代码更加简洁和易于维护。

希望这篇博客能帮助大家更好地理解 Spring Boot 的启动原理,并在实际开发中更好地应用这一强大的框架。

相关推荐

  1. 深入理解 Spring Boot 启动原理

    2024-06-07 11:32:02       34 阅读
  2. SpringBoot启动原理

    2024-06-07 11:32:02       37 阅读
  3. 深入理解springboot

    2024-06-07 11:32:02       128 阅读
  4. SpringBootspringboot启动初步理解

    2024-06-07 11:32:02       36 阅读
  5. 深入理解Elasticsearch高效原理

    2024-06-07 11:32:02       42 阅读
  6. 深入理解ChatGPT工作原理

    2024-06-07 11:32:02       32 阅读
  7. 玩转springbootspringboot启动原理

    2024-06-07 11:32:02       23 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-07 11:32:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-07 11:32:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-07 11:32:02       87 阅读
  4. Python语言-面向对象

    2024-06-07 11:32:02       96 阅读

热门阅读

  1. transformers DataCollator介绍

    2024-06-07 11:32:02       33 阅读
  2. 事务 ---- mysql

    2024-06-07 11:32:02       31 阅读
  3. python的视频处理FFmpeg库使用

    2024-06-07 11:32:02       31 阅读
  4. C# 证件照替换底色与设置背景图---PaddleSegSharp

    2024-06-07 11:32:02       26 阅读
  5. 详解MySQL的间隙锁

    2024-06-07 11:32:02       29 阅读
  6. mm-qcamera-daemon主函数分析

    2024-06-07 11:32:02       32 阅读
  7. Mysql基础进阶速成版

    2024-06-07 11:32:02       33 阅读
  8. 在 Vue 中实现算法可视化

    2024-06-07 11:32:02       31 阅读
  9. Elixir学习笔记——关键字列表和映射

    2024-06-07 11:32:02       35 阅读
  10. SwiftUI二列表和导航

    2024-06-07 11:32:02       23 阅读