SpringBoot 属性加载
一个 SpringBoot 应用的配置属性可以有多种不同的来源, 比如可以来自操作系统的环境变量, 比如可以来自 application.yaml 文件; 每一种不同的属性来源, 都会被 SpringBoot 封装成一个PropertySource
对象, 保存在 Environment
对象的 PropertySources
类型成员的 propertySourceList
中;
一个PropertySource
对象中就通过一个 Map 保存了这个属性源下的所有属性配置;
例如application.yaml
文件中的配置会被保存到一个OrginTrackedMapPropertySource
对象中;
这些属性源在 List 中的顺序决定了他们的优先级;
因为无论是通过@Value
注解还是 @ConfigurationProperties
注解去获取属性值, 其本质都是调用了 Environment::getProperty
方法; 具体获取的过程下面会讲到;
而这个方法的逻辑是顺序遍历所有属性源, 在遍历到的属性源中尝试去获取指定的属性, 如果找到了就直接返回; 所以在propertySourceList
中越靠前, 属性源的优先级就越高;
在 SpringApplication
的 run
方法内, prepareContext
之前, 先调用prepareEnvironment
方法, 准备应用环境,加载各种属性源, 包括系统变量,环境变量,命令行参数,默认变量, 配置文件等;
不了解SpringBoot启动过程看这篇文章 http://t.csdnimg.cn/qqs6G
属性源优先级
优先级从高到低
- Nacos 配置中心的配置;
- 当前应用的命名行参数;
- JAVA 的系统属性, 也就是来自JVM的启动时给的参数;
- 操作系统的环境变量;
- application-xxx.yaml, 例如 application-dev.yaml
- application.yaml
- boostrap.yaml
- @PropertySource 注解指定的配置文件;
- 默认属性
SpringBoot官网对优先级的描述:
Spring Boot uses a very particular order that is designed to allow sensible overriding of values. Later property sources can override the values defined in earlier ones. Sources are considered in the following order:PropertySource
- Default properties (specified by setting ).
SpringApplication.setDefaultProperties
@PropertySource
annotations on your classes. Please note that such property sources are not added to the until the application context is being refreshed. This is too late to configure certain properties such as and which are read before refresh begins.- Config data (such as files).
application.properties
- A that has properties only in .
RandomValuePropertySource``random.*
- OS environment variables.
- Java System properties ().
System.getProperties()
- JNDI attributes from .
java:comp/env
ServletContext
init parameters.ServletConfig
init parameters.- Properties from (inline JSON embedded in an environment variable or system property).
SPRING_APPLICATION_JSON
- Command line arguments.
properties
attribute on your tests. Available on@SpringBootTest
and the test annotations for testing a particular slice of your application.@TestPropertySource
annotations on your tests.- Devtools global settings properties in the directory when devtools is active.
$HOME/.config/spring-boot
举例 : @Value 注解
my:addr: localhost:7770
@Value("${my.addr}")
String addr;
总结来说是通过 BeanPostProcessor
, 在 Bean 实例化以后, 调用 Environment::getProperoty
获取属性值, 然后通过反射注入到 bean 中;
@Value 注解的详细分析参考这篇文章
@Autowired 与 @Value 作用原理详解