SpringBoot 之属性加载详解
SpringBoot 之属性加载详解
加载 property 顺序
Spring Boot 加载 property 顺序如下:
- Devtools 全局配置 (当 devtools 被激活
~/.spring-boot-devtools.properties
). - 测试环境中的
@TestPropertySource
注解配置 - 测试环境中的属性
properties
:@SpringBootTest
和 测试注解. - 命令行参数
SPRING_APPLICATION_JSON
属性ServletConfig
初始化参数ServletContext
初始化参数- JNDI attributes from 通过
java:comp/env
配置的 JNDI 属性 - Java 系统属性 (
System.getProperties()
) - 操作系统环境比那里
RandomValuePropertySource
加载random.*
形式的属性- jar 包外的
application-{profile}.properties
或application-{profile}.yml
配置 - jar 包内的
application-{profile}.properties
或application-{profile}.yml
配置 - jar 包外的
application.properties
或application.yml
配置 - jar 包内的
application.properties
或application.yml
配置 @PropertySource
绑定的配置- 默认属性 (通过
SpringApplication.setDefaultProperties
指定)
随机属性
RandomValuePropertySource
类用于配置随机值。
示例:
1 | my.secret=${random.value} |
命令行属性
默认情况下, SpringApplication
会获取 --
参数(例如 --server.port=9000
),并将这个 property
添加到 Spring 的 Environment
中。
如果不想加载命令行属性,可以通过 SpringApplication.setAddCommandLineProperties(false)
禁用。
Application 属性文件
SpringApplication
会自动加载以下路径下的 application.properties
配置文件,将其中的属性读到 Spring 的 Environment
中。
- 当前目录的
/config
子目录 - 当前目录
- classpath 路径下的
/config
package - classpath 根路径
注:
以上列表的配置文件会根据顺序,后序的配置会覆盖前序的配置。
你可以选择 YAML(yml) 配置文件替换 properties 配置文件。
如果不喜欢 application.properties
作为配置文件名,可以使用 spring.config.name
环境变量替换:
1 | $ java -jar myproject.jar --spring.config.name=myproject |
可以使用 spring.config.location
环境变量指定配置文件路径:
1 | $ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties |
Profile 特定属性
如果定义 application-{profile}.properties
形式的配置文件,将被视为 profile
环境下的特定配置。
可以通过 spring.profiles.active
参数来激活 profile,如果没有激活的 profile,默认会加载 application-default.properties
中的配置。
属性中的占位符
application.properties
中的值会被 Environment
过滤,所以,可以引用之前定义的属性。
1 | app.name=MyApp |
注:你可以使用此技术来创建 Spring Boot 属性变量。请参考: Section 77.4, “Use ‘Short’ Command Line Arguments
YAML 属性
Spring 框架有两个类支持加载 YAML 文件。
YamlPropertiesFactoryBean
将 YAML 文件的配置加载为Properties
。YamlMapFactoryBean
将 YAML 文件的配置加载为Map
。
示例 1
1 | environments: |
等价于:
1 | environments.dev.url=http://dev.example.com |
YAML 支持列表形式,等价于 property 中的 [index]
:
1 | my: |
等价于
1 | my.servers[0]=dev.example.com |
访问属性
YamlPropertySourceLoader
类会将 YAML 配置转化为 Spring Environment
类中的 PropertySource
。然后,你可以如同 properties 文件中的属性一样,使用 @Value
注解来访问 YAML 中配置的属性。
多 profile 配置
1 | server: |
YAML 的缺点
注:YAML 注解中的属性不能通过 @PropertySource
注解来访问。所以,如果你的项目中使用了一些自定义属性文件,建议不要用 YAML。
属性前缀
1 | package com.example; |
相当于支持配置以下属性:
acme.enabled
acme.remote-address
acme.security.username
acme.security.password
acme.security.roles
然后,你需要使用 @EnableConfigurationProperties
注解将属性类注入配置类中。
1 |
|
属性松散绑定规则
Spring Boot 属性名绑定比较松散。
以下属性 key 都是等价的:
Property | Note |
---|---|
acme.my-project.person.first-name |
- 分隔 |
acme.myProject.person.firstName |
驼峰命名 |
acme.my_project.person.first_name |
_ 分隔 |
ACME_MYPROJECT_PERSON_FIRSTNAME |
大写字母 |
属性转换
如果需要类型转换,你可以提供一个 ConversionService
bean (一个名叫 conversionService
的 bean) 或自定义属性配置 (一个 CustomEditorConfigurer
bean) 或自定义的 Converters
(被 @ConfigurationPropertiesBinding
注解修饰的 bena)。
时间单位转换
Spring 使用 java.time.Duration
类代表时间大小,以下场景适用:
- 除非指定
@DurationUnit
,否则一个 long 代表的时间为毫秒。 - ISO-8601 标准格式(
java.time.Duration
的实现就是参照此标准) - 你也可以使用以下支持的单位:
ns
- 纳秒us
- 微秒ms
- 毫秒s
- 秒m
- 分h
- 时d
- 天
示例:
1 |
|
数据大小转换
Spring 使用 DataSize
类代表数据大小,以下场景适用:
- long 值(默认视为 byte)
- 你也可以使用以下支持的单位:
B
KB
MB
GB
TB
示例:
1 |
|
校验属性
1 |
|
你也可以自定义一个名为 configurationPropertiesValidator
的校验器 Bean。获取这个 @Bean
的方法必须声明为 static
。
示例源码
示例源码:spring-boot-property