分享

spring-boot 配置从使用到原理

 新用户0175WbuX 2022-02-16

spring-boot 配置从使用到原理

  spring-boot的配置包括:

  自动配置

  外化配置

  外化配置通过将可变量分离出来,使得我们可以在不同的环境中使用同一份代码。

  外化配置表现形式不单单是 perties 和 .yml 属性文件,还可以使用环境变量和命令行参数等来实现。

  由于有好多外部配置来源,所以需要解决配置冲突问题,解决方案是通过优先级,下面是属性读取顺序:

  spring-boot 配置从使用到原理

  本地 Devtools 全局配置

  测试时 @TestPropertySource 注解配置

  测试时 @SpringBootTest 注解的 properties 配置

  命令行配置

  SPRINGAPPLICATIONJSON 配置

  ServletConfig 初始化参数配置

  ServletContext 初始化参数配置

  Java 环境的 JNDI 参数配置

  Java 系统的属性配置

  OS 环境变量配置

  只能随机属性的 RandomValuePropertySource 配置

  工程 jar 之外的多环境配置文件(application- {profile}perties 或 YAML)

  工程 jar 之内的多环境配置文件(application- {profile}perties 或 YAML)

  工程 jar 之外的应用配置文件(applicationperties 或 YAML)

  工程 jar 之内的应用配置文件(applicationperties 或 YAML)

  @Configuration 类中的 @PropertySource 注解配置

  默认属性配置(

  SpringApplication.setDefaultProperties 指定)

  讲了配置后,下一步就是介绍使用方法了:

  通过@Value注解

  通过@ConfigurationProperties绑定到配置类上

  通过Environment获取

  先看第一个@Value注解

  spring-boot 配置从使用到原理

  spring-boot 配置从使用到原理

  第二个@ConfigurationProperties注解

  这个东西是个啥呢?看代码:

  spring-boot 配置从使用到原理

  顺着代码注释我们去看

  ConfigurationPropertiesBindingPostProcessor和

  EnableConfigurationProperties。

  我们先来看

  ConfigurationPropertiesBindingPostProcessor:

  spring-boot 配置从使用到原理

  上面继承图中 ApplicationContextAware 是 Spring 提供的获取 Spring 上下文中指定对象的方法,会在 BeanPostProcessor 之前调用,我们先来看 BeanPostProcessor。

  BeanPostProcessor 接口定义了两个方法:

  postProcessBeforeInitialization:在 Bean 初始化回调前调用

  postProcessAfterInitialization:在 Bean 初始化回调完成后进行调用,而且会在 afterPropertiesSet 方法回调之后。

  所以我们只需要实现BeanPostProcessor接口,就能够控制Bean初始化前后的操作。

  下面我们来探究下到底是怎么实现的,查看实现的原理的万能方式是打断点调试,来看下我们调用栈:

  spring-boot 配置从使用到原理

  我们先来看第一个方法:

  AbstractAutowireCapableBeanFactory.initializeBean,

  spring-boot 配置从使用到原理

  上面我们列举出了主要的方法,看名字大概就能知道功能,来看

  applyBeanPostProcessorsAfterInitialization。

  spring-boot 配置从使用到原理

  看里面的重点函数getBeanPostProcessors。

  spring-boot 配置从使用到原理

  spring-boot 配置从使用到原理

  spring-boot 配置从使用到原理

  InitializingBean 中 afterPropertiesSet 方法处打断点。

  spring-boot 配置从使用到原理

  可以说是看到了老朋友,也是

  AbstractAutowireCapableBeanFactory.initializeBean方法,里面的initializeBean方法如下:

  spring-boot 配置从使用到原理

  spring-boot 配置从使用到原理

  还记得之前的图:

  spring-boot 配置从使用到原理

  介绍完

  ConfigurationPropertiesBindingPostProcessor 后,我们介绍

  EnableConfigurationProperties。

  spring-boot 配置从使用到原理

  @Import 可以将对应的 Bean 导入到 Spring 上下文中。如果类在工程中的话那么直接使用 @Configuration 注解即可,Spring 会自动识别的。但是如果在其他 jar 包或框架上,没有配置到自动扫描的目录中或者是没有添加 @Configuration 注解,那么就需要使用 @Import 将其导入到项目中来。

  spring-boot 配置从使用到原理

  spring-boot 配置从使用到原理

  spring-boot 配置从使用到原理

  到这里我们来捋下整个思路:

  我们的出发点是想看 为何加个注解 ConfigurationProperties 到类上,就能实现自动属性注入了

  我们去看了注解 ConfigurationProperties 的定义,注释中让我们去看

  ConfigurationPropertiesBindingPostProcessor 和

  EnableConfigurationProperties

  我们先去看了

  ConfigurationPropertiesBindingPostProcessor ,给出了类的继承图,上面需要关注的是 BeanPostProcessor 和 InitializingBean

  BeanPostProcessor 和 InitializingBean 一起给加载 Bean 的过程中流出了3个扩展点,调用的顺序是:

  postProcessBeforeInitialization -> afterPropertiesSet ->

  postProcessAfterInitialization

  在

  postProcessBeforeInitialization 中完成了属性的绑定

  接着我们要去看

  EnableConfigurationProperties 注解,发现里面的@Import是加载需要的Bean进来

  以上就是我们目前的一个解决问题的思路,下面我们来看

  EnableConfigurationProperties 这个Enable**是在哪个地方引入到SpringBoot中的呢?

  我们会发现在包

  org.springframework.boot.autoconfigure下的

  context.ConfigurationPropertiesAutoConfiguration:

  spring-boot 配置从使用到原理

  至于

  ConfigurationPropertiesAutoConfiguration 这个加载进来呢?

  这就到了 Spring-boot的精髓 EnableAutoConfiguration 。

  我们可以在包

  org.springframework.boot.autoconfigure中的spring.factories中定义了好多自动配置的类:

  spring-boot 配置从使用到原理

  所以我们就到了EnableAutoConfiguration:

  spring-boot 配置从使用到原理

  接着我们就会到了@SpringBootApplication,里面有注解 EnableAutoConfiguration

  spring-boot 配置从使用到原理

  我们下一步自然就进入@Import(

  AutoConfigurationImportSelector.class),里面的 selectImports 将 Bean 加载进来:

  spring-boot 配置从使用到原理

  其中 DeferredImportSelector 的作用是在所有Bean处理完后最后再处理,特别适合Bean是根据条件Import进来的。

  spring-boot 配置从使用到原理

  挨行来看代码,

  spring-boot 配置从使用到原理

  读取了

  META-INF/spring-autoconfigure-metadataperties 配置文件,改配置文件中的内容如下:

  spring-boot 配置从使用到原理

  乐器培训配置文件中配置了 SpringBoot 自动集成的各种 Enable 框架的执行条件,比如定义与其他 AutoConfiguration 框架的执行顺序,需要哪些 Bean 在的时候才可以执行等。

  spring-boot 配置从使用到原理

  整个流程如下:

  spring-boot 配置从使用到原理

  图片来自 第05课:@EnableAutoConfiguration 原理与实战

  到这我们将介绍我们最后一部分,我们了解了

  EnableConfigurationProperties 是如何开启的了,下面就看其加载进入了哪些Bean进来。

  spring-boot 配置从使用到原理

  我们先不看代码,先讲下这个逻辑,我们有@SpringBootApplication,其开启了@EnableAutoConfiguration,而 @EnableAutoConfiguration 会通过@Import去加载进

  META-INF/spring-autoconfigure-metadataperties 中定义的 autoconfigure 类来, 而其中就包含了

  EnableConfigurationProperties,下面我们就看看

  EnableConfigurationProperties 的 @Import 去将有相关 的Bean加载进来了,整个逻辑清晰后,我们就能来看

  EnableConfigurationPropertiesImportSelector 了,具体方法还是打断点,里面会有两个方法来注册Bean。

  spring-boot 配置从使用到原理

  会将

  EnableConfigurationProperties 中写的Bean注册进来,一个例子就是:

  spring-boot 配置从使用到原理

  上面会将JacksonProperties加载进来。

  spring-boot 配置从使用到原理

  这里就将我们之前介绍的

  ConfigurationPropertiesBindingPostProcessor加载了进来。

  总结

  以上就是我们的整个spring-boot的配置原理解析,总结下整个思路:

  我们的出发点是想看 为何加个注解 ConfigurationProperties 到类上,就能实现自动属性注入了

  我们去看了注解 ConfigurationProperties 的定义,注释中让我们去看

  ConfigurationPropertiesBindingPostProcessor 和

  EnableConfigurationProperties

  我们先去看了

  ConfigurationPropertiesBindingPostProcessor ,给出了类的继承图,上面需要关注的是 BeanPostProcessor 和 InitializingBean

  BeanPostProcessor 和 InitializingBean 一起给加载 Bean 的过程中流出了3个扩展点,调用的顺序是:

  postProcessBeforeInitialization -> afterPropertiesSet ->

  postProcessAfterInitialization

  在

  postProcessBeforeInitialization 中完成了属性的绑定

  接着我们要去看

  EnableConfigurationProperties 注解,发现里面的@Import是加载需要的Bean进来

  EnableConfigurationProperties @Import 进来的Bean就包含了之前的

  ConfigurationPropertiesBindingPostProcessor

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多