Spring Boot 自动配置简单流程

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".

以上就依赖于 自动配置!


使用 SSM 时,需要做大量的配置,较为繁琐

而在使用 Spring Boot 时,如果需要引入某个依赖,则直接引入 jar 包,进行配置(可能是增加某个注解),最后按需在 yml 中进行配置即可。

Spring Boot 相较于 SSM 使用上更加的方便,而这得益于 自动配置

自动配置是什么?


自动配置 就是通过一些简单的配置实现某些功能。

而自动配置则是基于 Spring FrameworkSPI 机制实现的。

SPI 机制:SPI机制简介-CSDN博客

自动配置是如何实现的


以下是自动配置的基本流程,此处所指的配置文件非 yml

  1. 读取 配置文件
  2. 过滤 配置文件内的类
  3. Bean 的实例化、初始化、使用、销毁

众所周知,自动配置依赖于 @SpringBootApplication 所导入的 AutoConfigurationImportSelector 去读取 spring.factories 或 org.springframework.boot.autoconfigure.AutoConfiguration.imports。

配置文件种类


配置文件有两类

  • spring.factories
  • org.springframework.boot.autoconfigure.AutoConfiguration.imports

spring.factories 作用于 2.7 之前

*.imports 作用于 2.7 之后

但两者差异只是存储的位置不一样。

读取配置文件


配置文件的加载依赖于 Spring 对 @Import 的处理。

@Import 主要由 ConfigurationClassPostProcessor 进行处理

ConfigurationClassPostProcessor

类图

Spring Boot 自动配置简单流程_第1张图片

Spring refresh 时,会执行 BeanDefinitionRegistryPostProcessor 所有实现类对应的方法

最终会调用 ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry,开始进行自动配置的处理。

具体逻辑详见:

AbstractApplicationContext#refresh ->

AbstractApplicationContext#invokeBeanFactoryPostProcessors ->

PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors

最终会调用 AutoConfigurationImportSelector#getAutoConfigurationEntry 完成对配置文件的加载。

断点打到 AutoConfigurationImportSelector#getAutoConfigurationEntry 可以看具体执行流程。

该方法由 DeferredImportSelector.Group 的实现类进行调用。

DeferredImportSelector

该接口存在内部接口 GroupAutoConfigurationImportSelector 也实现了这个接口,再通过该接口的 #process 完成对配置文件的加载

过滤配置文件内的类


自动配置不会把文件内所有的配置类都加载进容器内,因此需要进行筛选过滤。

主要依赖于 SpringBootCondition,此类亦是 Condition 的实现类。

SpringBootCondition 采用了模板方法模式,实现类在 #getMatchOutcome 中,实现个性化的处理逻辑

类图:

Spring Boot 自动配置简单流程_第2张图片


网上文章说对应的条件关系会存储在 META-INF/spring-autoconfigure-metadata.properties 中.

源码中未找到,但正常 Spring Boot 项目中存在

但源码中有文档说明:

“Spring Boot uses an annotation processor to collect the conditions on auto-configurations in a metadata file (`META-INF/spring-autoconfigure-metadata.properties`).

If that file is present, it is used to eagerly filter auto-configurations that do not match, which will improve startup time.

It is recommended to add the following dependency in a module that contains auto-configurations:”

[source,xml,indent=0,subs="verbatim"]

----

org.springframework.boot

spring-boot-autoconfigure-processor

true

----

具体的过滤步骤

基本概念:

OnBeanCondition:是否存在某个 bean

OnClassCondition:是否存在某个类

OnResource:是否存在某些资源

OnPropertyCondition:是否存在某些属性

过滤分为三处:

  1. #getAutoConfigurationEntry 方法内
  2. #process 方法处理完成后
  3. 加载 BeanDefinition 时

#getAutoConfigurationEntry 是 #process 内部调用的,用于解析配置文件。

#process 则是 AutoConfigurationImportSelector.AutoConfigurationGroup 的方法。

1. #getAutoConfigurationEntry 方法内

位于 AutoConfigurationImportFilter#match

此处仅是检查类路径中是否存在这个类,只处理了 OnBeanCondition、OnClassCondition 

2. #process 方法处理完成后

位于

ConfigurationClassParser#processImports ->

ConfigurationClassParser#processConfigurationClass ->

ConditionEvaluator#shouldSkip ->

SpringBootCondition#matches

OnPropertyCondition、OnResource 在此处进行处理。

OnPropertyCondition 是检测 Spring 中是否包含了该属性。

OnResource 应该是资源。

Spring Boot 的对 yml 的解析在 Spring 容器启动器前,就已完成加载。

3. 加载 BeanDefinition 时

此时的 “加载 BeanDefinition” 并非 Spring 容器正常的加载 BeanDefinition,而是在加载 配置文件后,获得其全类名所进行的一次 BeanDefinition 的加载。

位于 ConfigurationClassBeanDefinitionReader#loadBeanDefinitions

OnBeanCondition 在此进行处理。

是通过 BeanFactory#getBeanNamesForType 去检查容器内有没有相关信息

Bean 的实例化、初始化、使用、销毁


后续与正常 Bean 的生命周期一致。

Bean 的生命周期:Spring Bean生命周期详解_spring bean的生命周期-CSDN博客

Starter 的实现


Spring Boot之自定义Starter_springboot自定义starter-CSDN博客

一些特殊类


ImportBeanDefinitionRegistrar

主要用于注册 BeanDefinition。

此处以 Mybatis-starter 举例:

例子:Mybatis-SpringBoot 准备阶段简易流程-CSDN博客

@MapperScan 不存在时,则会由 AutoConfiguredMapperScannerRegistrar 完成对 MapperScannerConfigurer 进行加载,最终通过 MapperScannerConfigurer 完成对 mapper 接口的 BeanDefinition 的载入。

AutoConfiguredMapperScannerRegistrar 依赖于实现的 ImportBeanDefinitionRegistrar 接口的 registerBeanDefinitions 方法完成对 MapperScannerConfigurer 加载.

结束


一些流程需要自己去看下咯。

  1. ConfigurationClassPostProcessor 的处理流程
  2. yml 文件的加载
  3. Bean 的生命周期

你可能感兴趣的:(spring,boot,java)