Spring Boot的配置加载和PropertySource抽象

520 阅读2分钟

外化配置的加载顺序(高到低)

配置文件

  • 开启DevTools,~/.spring-boot-devtools.properties
  • 测试类@TestPropertySource
  • @SpringBootTest#properties属性
  • 命令行参数(--server.port=9000)
  • SPRING_APPLICATION_JSON中的属性

配置项

  • ServletConfig 初始化参数
  • ServletContext 初始化参数
  • java:comp/env中的JNDI属性
  • System.getProperties() 命令行的-D也可以指定系统参数的属性
  • OS环境变量
  • random.*涉及到的RandomValuePropertySource

application.properties
有profile的,jar包外部的优先

  • jar包外的application-{profile}.properties/.yml
  • jar包内的application-{profile}.properties/.yml
  • jar包外的application.properties/.yml
  • jar包内的application.properties/.yml
  • @Configuration类上的@PropertySource
  • SpringApplication.setDefaultProperties()设置的默认属性

Relaxed Binding

这些配置的来源在spring中都会被抽象为PropertySource

添加propertySource

想为系统提供更多的配置来源,所以只需提供propertysource即可 <context:property-placeholder>把properties中的属性变为spring可以获取到的配置项,本质就是帮我们注册了PropertySourcesPlaceHolderConfigurer(spring3.1之后的),从spring3.1开始就有PropertySource的抽象,把properties文件配置在@PropertySource注解的类中

Spring Boot中的@ConfigurationProperties(prefix="xxx.xxx")

  • 可将属性绑定到结构化对象上
  • 支持Relaxed Binding
  • 支持安全的类型转换
  • @EnableConfigurationProperties

定制PropertySource

主要步骤

  • 实现PropertySource
  • 从Environment取得PropertySources
  • PropertyResource要通过PropertiesPropertySourceLoader,和配置资源文件resource共同获取
  • 将自己的PropertySource添加到合适的位置,即注册到PropertySources中

切入位置

  • EnvironmentPostProcessor
  • BeanFactoryPostProcessor

实例

简单方法:添加@PropertySource的注解来实现
另一种方法:YapfEnvironmentPostProcessor.java如下
不用声明为bean,spring boot会找到这些类的实现,然后加载

实际应用

系统内部的配置中心,自己定制的,整合spring的propertyResource,提供这个配置中心所对应的PropertyResource的实现,然后把该PropertyResource注册到environment里面(PropertySources),这样spring就可以找到PropertyResource中的属性了,无论属性配在配置文件/上下文/配置中心,都是可以被找到的。