重识 Spring Boot 的内部结构、核心机制、工作原理(1~4节)

103 阅读5分钟

4.9 重识 Spring Boot 的内部结构、核心机制、工作原理;

课件:第9章.pdf

4.9.1 Spring Boot 的组成部分

image-20250404190934967

Spring Boot 旨在优化 Spring Framework 的使用体验。

1、Spring Boot 的核心特性
  1. 更快地创建独立可运行的 Spring 应用程序;
  2. 内嵌应用服务器(如Tomcat、Jetty);
  3. 简化Maven或Gradle配置;
  4. 提供自动配置,以减少XML配置和代码生成的需求。
2、Spring Boot 的四大核心
  1. 自动配置(Auto Configuration)
  2. 起步依赖(Starter Dependencies)
  3. 命令行界面(Command Line Interface)
  4. Actuator,提供运行时生产级特性,例如监控。

4.9.2 ⾃动配置的实现原理

1、了解自动配置

image-20250404191953555

  1. Spring Boot 自动配置是什么?它是如何工作的?

    • Spring Boot 的自动配置是一种基于类、application properties 或 环境上下文中的配置。根据这些信息自动对 Spring Boot 应用程序进行配置的功能。

    • 相关代码位于 spring-boot-auto-configuration 包中,并通过启用@EnableAutoConfiguration 注解,启动自动配置过程。

      SpringBootApplication 中已经自动添加了 EnableAutoConfiguration。

image-20250403230937628

  1. 如何排除某些自动配置类?
    • 可以在 @EnableAutoConfiguration 注解上使用exclude属性,指定要排除的自动配置类。
    • 例如,设置@EnableAutoConfiguration(exclude = {DataSourcesAutoConfiguration.class, ...}),排除了与数据源相关的自动配置。
2、⾃动配置的实现原理

image-20250404200030957

  1. Spring Boot 自动配置的具体实现原理是什么?

    • 实现自动配置的是 @EnableAutoConfiguration 注解。

    • 它会导入AutoConfigurationImportSelector,并加载 spring.factories 中的org.springframework.boot.autoconfigure.EnableAutoConfiguration 属性。

    • 该属性包含了所有 Spring Boot 提供的自动配置类,通过 各种条件注解(如@Conditional系列),来决定何时启用或禁用这些配置项。

  2. @EnableAutoConfiguration 源码追溯

image-20250403231151338

image-20250403233713367

image-20250403231339006

image-20250403231411427

image-20250403231455789

image-20250403231534879

image-20250404200239026

  1. 常用的条件注解
    • @Conditional,通用条件注解基类,需自定义条件判断逻辑(实现 Condition 接口)
    • @ConditionalOnClass, 当类路径(Classpath)中存在指定类时生效
    • @ConditionalOnBean, 当 Spring 容器中存在指定 Bean 时生效
    • @ConditionalOnMissingBean, 当 Spring 容器中缺少指定 Bean 时生效(常用于覆盖默认配置)
    • @ConditionalOnProperty, 根据配置文件中的属性值决定是否生效
3、⾃动配置 debug

image-20250404200739733

  1. 如何查看哪些自动配置生效了,哪些未生效?

    • 在命令行中添加--debug 标志,运行应用程序,
    • Spring Boot 会通过ConditionEvaluationReportListener 输出一个详细的报告。
    • 会显示所有匹配的自动配置项、未匹配的配置、被排除的配置、无条件配置的详情。
  2. IDEA 操作示例

image-20250403232747576

image-20250403232825661

image-20250403232849401

image-20250403232900038

4.9.3 实现⾃己的⾃动配置

1、主要⼯作内容

image-20250404200934542

  1. 实现一个自定义的 spring boot 自动配置,需要做哪些事情?

    • 编写一个配置类(configure),

    • 通过条件注解实现想要的自动配置;

    • 在 spring boot 的上下文中声明,并注册这个自定义自动配置类;

2、常用的条件注解

image-20250404201127602

image-20250404201213126

image-20250404201149470

3、⾃动配置的执行顺序

image-20250404201424481

  1. 如何指定自定义自动配置的执行顺序?
    • @AutoConfigureBefore ,指定自定义自动配置在其他自动配置类之前执行。
    • `@AutoConfigureAfter ,指定自定义自动配置在其他自动配置类之后执行。
    • @AutoConfigureOrder ,设定多个自动配置的执行顺序。
4、show me the code
  1. 如何在 spring boot 项目中引入并使用自定义模块?
    • 在项目的 pom.xml 文件中引入所需的依赖项,并通过创建新的模块将这些依赖整合进来。
    • 在主程序中,通过@EnableAutoConfiguration注解启用自动配置,
    • 并在AutoConfiguration类中编写条件判断及自动配置逻辑,确保只有在满足特定条件时才创建和配置相应的bean。

image-20250404202220850

image-20250404202401364

image-20250403235750634

image-20250403235805928

image-20250404001323730

image-20250404202726136

image-20250404202827346

image-20250404001452522

4.9.4 如何在低版本 Spring 中,实现自动配置

1、需求与问题

image-20250404203031861

2、核⼼解决思路

image-20250404203112781

  1. 在低版本的spring中如何实现自动配置?如何在不升级Spring版本的前提下为现有系统添加功能增强?
    • 在使用 spring 4 以下版本时,由于没有条件注解,无法像新版本那样通过自动配置功能对现有系统做统一增强。
    • 通过使用 BeanFactoryPostProcessor 和自定义 java configure,在保持原有代码不变的情况下,可以在 Spring 的 bean 初始化阶段实现条件判断与配置加载。
    • 具体做法是,在bean 初始化之后通过 BeanFactoryPostProcessor 对 bean 实例进行增强处理,并在 component-scan 中引入自定义的 java configure,使其能被Spring加载和管理。
3、Spring 的两个扩展点

image-20250404203322295

4、关于 Bean 的⼀些定制

image-20250404215244929

  1. 对于 Spring bean 的生命周期管理有哪些定制方式?

    • Spring bean 的生命周期包括 初始化阶段 和 销毁阶段 。

    • 在初始化阶段,可以实现 InitializingBean 接口,使用 @PostConstruct注解、指定 init-method 等方式,在 bean 创建后调用特定方法。

    • 在销毁阶段,可以实现 DisposableBean 接口,Spring 会在回收 bean 时调用相应方法;另外,也可以通过添加 @PreDestroy 注解的方法,在销毁前进行调用。

  2. Spring 如何在 bean 的生命周期,避免常见错误?

    • 在 Spring 中,当获取 bean 时(如通过 getBean 方法),其创建过程会在doGetBean方法中执行。
    • doGetBean的实现过程中,Spring 会尝试在创建 bean 后注册 并执行 dispose方法(如果有)。
    • 即使 bean 没有实现 DisposableBean接口,只要它有 close 或销毁的方法,Spring 在销毁该 bean 时也会调用这些方法,从而确保了资源的安全释放,避免潜在的内存泄漏等问题。

image-20250404214704217

5、⼀些常用操作

image-20250404215333089

  1. 在Spring中,如何判断一个类是否存在?

    • 可以通过 Spring 提供的 ClassUtils 类来判断。调用其 isPresent 方法即可判断指定类是否存在于class path中。
  2. 如何判断某个bean是否已经被定义了?

    • 可以使用 ListableBeanFactory.containsBeanDefinition() 的方法进行判断,
    • 通过 ListableBeanFactory.getBeanNamesForType() 查看特定类型的 bean 有哪些已经定义的名字。
  3. 如何在没有 BeanDefinitionRegistry 的情况下,定义一个新的 bean?

    • 可以通过 BeanFactory.registerSingleton() 方法来定义新的 bean。
    • 如果,已经有一个名为 BeanDefinitionRegistry 的注册表,则可以通过调用相关方法进行定义。
6、show me the code

geektime-autoconfigure-backport

image-20250404215701658

image-20250404220521774

image-20250404220543072

image-20250404220558909