外化配置的加载顺序(高到低)
配置文件
- 开启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
实例
另一种方法:YapfEnvironmentPostProcessor.java如下
不用声明为bean,spring boot会找到这些类的实现,然后加载
实际应用
系统内部的配置中心,自己定制的,整合spring的propertyResource,提供这个配置中心所对应的PropertyResource的实现,然后把该PropertyResource注册到environment里面(PropertySources),这样spring就可以找到PropertyResource中的属性了,无论属性配在配置文件/上下文/配置中心,都是可以被找到的。