4.9 重识 Spring Boot 的内部结构、核心机制、工作原理;
4.9.1 Spring Boot 的组成部分
Spring Boot 旨在优化 Spring Framework 的使用体验。
1、Spring Boot 的核心特性
- 更快地创建独立可运行的 Spring 应用程序;
- 内嵌应用服务器(如Tomcat、Jetty);
- 简化Maven或Gradle配置;
- 提供自动配置,以减少XML配置和代码生成的需求。
2、Spring Boot 的四大核心
- 自动配置(Auto Configuration)
- 起步依赖(Starter Dependencies)
- 命令行界面(Command Line Interface)
- Actuator,提供运行时生产级特性,例如监控。
4.9.2 ⾃动配置的实现原理
1、了解自动配置
-
Spring Boot 自动配置是什么?它是如何工作的?
-
Spring Boot 的自动配置是一种基于类、application properties 或 环境上下文中的配置。根据这些信息自动对 Spring Boot 应用程序进行配置的功能。
-
相关代码位于 spring-boot-auto-configuration 包中,并通过启用
@EnableAutoConfiguration注解,启动自动配置过程。SpringBootApplication 中已经自动添加了 EnableAutoConfiguration。
-
- 如何排除某些自动配置类?
- 可以在
@EnableAutoConfiguration注解上使用exclude属性,指定要排除的自动配置类。 - 例如,设置
@EnableAutoConfiguration(exclude = {DataSourcesAutoConfiguration.class, ...}),排除了与数据源相关的自动配置。
- 可以在
2、⾃动配置的实现原理
-
Spring Boot 自动配置的具体实现原理是什么?
-
实现自动配置的是
@EnableAutoConfiguration注解。 -
它会导入
AutoConfigurationImportSelector,并加载spring.factories中的org.springframework.boot.autoconfigure.EnableAutoConfiguration属性。 -
该属性包含了所有 Spring Boot 提供的自动配置类,通过 各种条件注解(如
@Conditional系列),来决定何时启用或禁用这些配置项。
-
-
@EnableAutoConfiguration源码追溯
- 常用的条件注解
- @Conditional,通用条件注解基类,需自定义条件判断逻辑(实现
Condition接口) - @ConditionalOnClass, 当类路径(Classpath)中存在指定类时生效
- @ConditionalOnBean, 当 Spring 容器中存在指定 Bean 时生效
- @ConditionalOnMissingBean, 当 Spring 容器中缺少指定 Bean 时生效(常用于覆盖默认配置)
- @ConditionalOnProperty, 根据配置文件中的属性值决定是否生效
- @Conditional,通用条件注解基类,需自定义条件判断逻辑(实现
3、⾃动配置 debug
-
如何查看哪些自动配置生效了,哪些未生效?
- 在命令行中添加
--debug标志,运行应用程序, - Spring Boot 会通过
ConditionEvaluationReportListener输出一个详细的报告。 - 会显示所有匹配的自动配置项、未匹配的配置、被排除的配置、无条件配置的详情。
- 在命令行中添加
-
IDEA 操作示例
4.9.3 实现⾃己的⾃动配置
1、主要⼯作内容
-
实现一个自定义的 spring boot 自动配置,需要做哪些事情?
-
编写一个配置类(configure),
-
通过条件注解实现想要的自动配置;
-
在 spring boot 的上下文中声明,并注册这个自定义自动配置类;
-
2、常用的条件注解
3、⾃动配置的执行顺序
- 如何指定自定义自动配置的执行顺序?
@AutoConfigureBefore,指定自定义自动配置在其他自动配置类之前执行。- `@AutoConfigureAfter ,指定自定义自动配置在其他自动配置类之后执行。
@AutoConfigureOrder,设定多个自动配置的执行顺序。
4、show me the code
- 如何在 spring boot 项目中引入并使用自定义模块?
- 在项目的 pom.xml 文件中引入所需的依赖项,并通过创建新的模块将这些依赖整合进来。
- 在主程序中,通过
@EnableAutoConfiguration注解启用自动配置, - 并在
AutoConfiguration类中编写条件判断及自动配置逻辑,确保只有在满足特定条件时才创建和配置相应的bean。
4.9.4 如何在低版本 Spring 中,实现自动配置
1、需求与问题
2、核⼼解决思路
- 在低版本的spring中如何实现自动配置?如何在不升级Spring版本的前提下为现有系统添加功能增强?
- 在使用 spring 4 以下版本时,由于没有条件注解,无法像新版本那样通过自动配置功能对现有系统做统一增强。
- 通过使用
BeanFactoryPostProcessor和自定义 java configure,在保持原有代码不变的情况下,可以在 Spring 的 bean 初始化阶段实现条件判断与配置加载。 - 具体做法是,在bean 初始化之后通过
BeanFactoryPostProcessor对 bean 实例进行增强处理,并在component-scan中引入自定义的 java configure,使其能被Spring加载和管理。
3、Spring 的两个扩展点
4、关于 Bean 的⼀些定制
-
对于 Spring bean 的生命周期管理有哪些定制方式?
-
Spring bean 的生命周期包括 初始化阶段 和 销毁阶段 。
-
在初始化阶段,可以实现 InitializingBean 接口,使用
@PostConstruct注解、指定 init-method 等方式,在 bean 创建后调用特定方法。 -
在销毁阶段,可以实现 DisposableBean 接口,Spring 会在回收 bean 时调用相应方法;另外,也可以通过添加
@PreDestroy注解的方法,在销毁前进行调用。
-
-
Spring 如何在 bean 的生命周期,避免常见错误?
- 在 Spring 中,当获取 bean 时(如通过 getBean 方法),其创建过程会在
doGetBean方法中执行。 - 在
doGetBean的实现过程中,Spring 会尝试在创建 bean 后注册 并执行 dispose方法(如果有)。 - 即使 bean 没有实现 DisposableBean接口,只要它有 close 或销毁的方法,Spring 在销毁该 bean 时也会调用这些方法,从而确保了资源的安全释放,避免潜在的内存泄漏等问题。
- 在 Spring 中,当获取 bean 时(如通过 getBean 方法),其创建过程会在
5、⼀些常用操作
-
在Spring中,如何判断一个类是否存在?
- 可以通过 Spring 提供的 ClassUtils 类来判断。调用其 isPresent 方法即可判断指定类是否存在于class path中。
-
如何判断某个bean是否已经被定义了?
- 可以使用
ListableBeanFactory.containsBeanDefinition()的方法进行判断, - 通过
ListableBeanFactory.getBeanNamesForType()查看特定类型的 bean 有哪些已经定义的名字。
- 可以使用
-
如何在没有 BeanDefinitionRegistry 的情况下,定义一个新的 bean?
- 可以通过
BeanFactory.registerSingleton()方法来定义新的 bean。 - 如果,已经有一个名为
BeanDefinitionRegistry的注册表,则可以通过调用相关方法进行定义。
- 可以通过
6、show me the code
geektime-autoconfigure-backport