一、属性加载顺序
Spring Boot允许外化(externalize) 你的配置,这样你能够在不同的环境下使用相同的代码。 你可以使用properties文件,YAML文件,环境变量和命令行参数来外化配置。 使用@Value注解, 可以直接将属性值注入到你的beans中, 并通过Spring的Environment抽象或绑定到结构化对象来访问。
Spring Boot使用一个非常特别的PropertySource次序来允许对值进行合理的覆盖, 需要以下面的次序考虑属性:
1.命令行参数:java -jar ***.jar--spring.config.name=myproject.properties
2.来自于java:comp/env的JNDI属性
3. Java系统属性(System.getProperties())
4.操作系统环境变量
5.只有在random.*里包含的属性会产生一个RandomValuePropertySource
6.在打包的jar外的应用程序配置文件(application.properties, 包含YAML和profile变量)
7.在打包的jar内的应用程序配置文件(application.properties, 包含YAML和profile变量)
8.在@Configuration类上的@PropertySource注解
9.默认属性( 使用SpringApplication.setDefaultProperties指定)
二、Application属性文件
SpringApplication将从以下位置加载application.properties文件, 并把它们添加到Spring Environment中:
1.当前目录下的一个/config子目录
2.当前目录
3.一个classpath下的/config包
4. classpath根路径(root)
这个列表是按优先级排序的( 列表中位置高的将覆盖位置低的) 。
注:你可以使用YAML('.yml') 文件替代'.properties'。
如果不喜欢将application.properties作为配置文件名, 你可以通过指定spring.config.name环境属性来切换其他的名称。你也
可以使用spring.config.location环境属性来引用一个明确的路径(目录位置或文件路径列表以逗号分割) 。
$java -jar myproject.jar --spring.config.name=myproject
//or
$java -jar myproject.jar--spring.config.location=classpath:/default.properties,classpath:/override.properties
如果spring.config.location包含目录( 相对于文件), 那它们应该以/结尾( 在加载前,spring.config.name产生的名称将被追
加到后面) 。 不管spring.config.location是什么值, 默认的搜索路径classpath:,classpath:/config,file:,file:config/总会被使用。
以这种方式, 你可以在application.properties中为应用设置默认值, 然后在运行的时候使用不同的文件覆盖它, 同时保留默认
配置。
注:如果你使用环境变量而不是系统配置, 大多数操作系统不允许以句号分割(period-separated) 的key名称, 但你可以使
用下划线(underscores) 代替( 比如, 使用SPRING_CONFIG_NAME代替spring.config.name) 。 如果你的应用运行在一
个容器中, 那么JNDI属性(java:comp/env) 或servlet上下文初始化参数可以用来取代环境变量或系统属性,当然也可以使
用环境变量或系统属性
三、属性的解析
1、除了application.properties文件, 特定配置属性也能通过命令惯例application-{profile}.properties来定义。 特定Profile属性从跟
标准application.properties相同的路径加载, 并且特定profile文件会覆盖默认的配置。
2、当application.properties里的值被使用时, 它们会被存在的Environment过滤, 所以你能够引用先前定义的值( 比如, 系统属
性) 。
app.name=MyApp
app.description=${app.name} is a Spring Boot application
也能在Bean中直接使用@Value
3、YAML是JSON的一个超集, 也是一种方便的定义层次配置数据的格式。 无论你何时将SnakeYAML库放到classpath下,
SpringApplication类都会自动支持YAML作为properties的替换。
注:如果你使用'starter POMs',spring-boot-starter会自动提供SnakeYAML。
4、可以直接使用@Value注入到bean中
5、你可以在单个文件中定义多个特定配置(profile-specific) 的YAML文档, 并通过一个spring.profiles key标示应用的文档。 例
如:
#default
server:
address: 192.168.1.100
#--development profile
spring:
profiles: development
server:
address: 127.0.0.1
#---production profile
spring:
profiles: production
server:
address: 192.168.1.120
在上面的例子中, 如果development配置被激活, 那server.address属性将是127.0.0.1。 如果development和production配置
( profiles) 没有启用,则该属性的值将是192.168.1.100。
6、application.properties和application.yml的区别是yml不能被@PropertySource注解加载
四、自动载入外化属性到Bean(Boot更推荐的方式)
1、当@EnableConfigurationProperties注解应用到你的@Configuration时, 任何被@ConfigurationProperties注解的beans将自
动被Environment属性配置。 这种风格的配置特别适合与SpringApplication的外部YAML配置进行配合使用。
为了使用@ConfigurationProperties beans, 你可以使用与其他任何bean相同的方式注入它们
可以在@ConfigurationProperties中指明prefix,定义你的映射规则,简化配置
2、你可以通过在@EnableConfigurationProperties注解中直接简单的列出属性类来快捷的注册@ConfigurationProperties bean
的定义
3、正如使用@ConfigurationProperties注解一个类, 你也可以在@Bean方法上使用它。 当你需要绑定属性到不受你控制的第三
方组件时, 这种方式非常有用
4、Spring Boot使用一些宽松的规则用于绑定Environment属性到@ConfigurationProperties beans, 所以Environment属性名和
bean属性名不需要精确匹配。 常见的示例中有用的包括虚线分割( 比如, context--path绑定到contextPath) 和将环境属性转
为大写字母( 比如, PORT绑定port)
5、Spring会尝试强制外部的应用属性在绑定到@ConfigurationProperties beans时类型是正确的。 如果需要自定义类型转换, 你
可以提供一个ConversionService bean( bean id为conversionService) 或自定义属性编辑器( 通过一个
CustomEditorConfigurer bean)
6、校验:Spring Boot将尝试校验外部的配置, 默认使用JSR-303( 如果在classpath路径中) 。 你可以轻松的为你的
@ConfigurationProperties类添加JSR-303 javax.validation约束注解 ,你也可以通过创建一个叫做configurationPropertiesValidator的bean来添加自定义的Spring Validator