赞
踩
SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用application.properties或者application.yml(application.yaml)进行配置。
SpringBoot默认会从Resources目录下加载application.properties或application.yml(application.yaml)文件
其中,application.properties文件是键值对类型的文件,之前一直在使用,所以此处不在对properties文件的格式进行阐述。除了properties文件外,SpringBoot还可以使用yml文件进行配置,下面对yml文件进行讲解。
YML文件格式是YAML (YAML Aint Markup Language)编写的文件格式,YAML是一种直观的能够被电脑识别的的数据数据序列化格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入,比如: C/C++, Ruby, Python, Java, Perl, C#, PHP等。YML文件是以数据为核心的,比传统的xml方式更加简洁。
YML文件的扩展名可以使用.yml或者.yaml。
在Spring Boot 2.0中对配置属性加载的时候会除了像1.x版本时候那样移除特殊字符外,还会将配置均以全小写的方式进行匹配和加载。所以,下面的4种配置方式都是等价的:
- spring.jpa.databaseplatform=mysql
- spring.jpa.database-platform=mysql
- spring.jpa.databasePlatform=mysql
- spring.JPA.database_platform=mysql
- spring:
- jpa:
- databaseplatform: mysql #行注释
- database-platform: mysql
- databasePlatform: mysql
- database_platform: mysql
注意:
-
分隔符的方式来配置,比如:spring.jpa.database-platform=mysql
在properties文件中使用[]
来定位列表类型,比如:
- student.name[0]=孙悟空
- student.name[1]=张三丰
也支持使用逗号分割的配置方式,上面与下面的配置是等价的:
student.name=孙悟空,张三丰
而在yaml文件中使用可以使用如下配置:
- student:
- name:
- - 孙悟空
- - 张三丰
注意 - 后有空格 出现关机字可以用""括起来
也支持逗号分割的方式:
- student:
- name: 孙悟空, 张三丰
或者
- student:
- name: [孙悟空, 张三丰]
集合中的元素是对象(或map)形式:
- student:
- - name: zhangsan
- age: 18
- score: 100
- - name: lisi
- age: 28
- score: 88
- - name: wangwu
- age: 38
- score: 90
properties格式的可以这样写:
student[0].name=迪丽热巴
student[0].age=21
student[1].name=古力娜扎
student[1].age=21
注意:在Spring Boot 2.0中对于List类型的配置必须是连续的,不然会抛出UnboundConfigurationPropertiesException
异常,所以如下配置是不允许的:
foo[0]=a
foo[2]=b
在Spring Boot 1.x中上述配置是可以的,foo[1]
由于没有配置,它的值会是null
Map类型在properties和yaml中的标准配置方式如下:
- spring.my-example.foo=bar
- spring.my-example.hello=world
- spring:
- my-example:
- foo: bar
- hello: world
注意:如果Map类型的key包含非字母数字和-
的字符,需要用[]
括起来,比如:
- spring:
- my-example:
- '[foo.baz]': bar
如果你想将Map<String,Object>
类型的配置绑定到application.properties
文件中,你可以按照以下方式进行配置。
在application.properties
文件中,你可以使用以下格式来定义每个配置项:
taskProperties.key1.target=value1
taskProperties.key1.threadCount=1
taskProperties.key2.target=value2
taskProperties.key2.threadCount=2
其中,key1
和key2
是Map
中的键,你可以根据需要添加更多的键值对。
Java 代码这样写:
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.stereotype.Component;
-
- import java.util.Map;
-
- @Component
- @ConfigurationProperties(prefix = "myapp")
- public class MyAppProperties {
- private Map<String, Task> taskProperties;
-
- public Map<String, Task> getTaskProperties() {
- return taskProperties;
- }
-
- public void setTaskProperties(Map<String, Task> taskProperties) {
- this.taskProperties = taskProperties;
- }
-
- public static class Task {
- private String target;
- private int threadCount;
-
- }
- }
使用注解@Value映射:
application.properties配置:
person.name=zhangsan
person.age=18
或者,application.yml配置:
person:
name: zhangsan
age: 18
@Value("${属性名}")
注解来加载对应的配置属性:- @Controller
- public class QuickStartController {
-
- @Value("${person.name}")
- private String name;
-
- //设置默认值,person.name:是空值
- @Value("${person.name:王大拿}")
- private String name2;
-
- @Value("${person.age}")
- private Integer age;
-
-
- @RequestMapping("/quick")
- @ResponseBody
- public String quick(){
- return "springboot 访问成功! name="+name+",age="+age;
- }
-
- }
使用@Value注入map、List稍微复杂
配置文件
- list: topic1,topic2,topic3
- maps: "{key1: 'value1', key2: 'value2'}
- maps2: "{key1: '[value1,value2]', key2: '[value1,value2]'}
实体类
- @Value("#{'${list}'.split(',')}")
- private List<String> list;
-
- @Value("#{${maps}}")
- private Map<String,String> maps;
-
- @Value("#{${maps}}")
- private Map<String,List<String>> maps;
通过注解@ConfigurationProperties(prefix="配置文件中的key的前缀,可以使properties文件也可以是yml文件")可以将配置文件中的配置自动与实体进行映射(这个注解能作用在类上也能作用在方法上)
实体Bean代码如下:
- @Controller
- //@PropertySource("classpath:/production/wxpay.properties") //的值是配置文件文件的路径
- @ConfigurationProperties(prefix = "person")//配置文件前缀
- public class QuickStartController {
-
- private String name;
- private Integer age;
-
- @RequestMapping("/quick")
- @ResponseBody
- public String quick(){
- return "springboot 访问成功! name="+name+",age="+age;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public void setAge(Integer age) {
- this.age = age;
- }
- }
注意:使用@ConfigurationProperties方式可以进行配置文件与实体字段的自动映射,但需要字段必须提供set方法才可以,而使用@Value注解修饰的字段不需要提供set方法
@PropertySource("classpath:/production/wxpay.properties") 的值是properties文件的路径,如果是默认配置文件可以不写此注解
@ConfigurationProperties(prefix = "wxpay") prefix属性值是配置文件key的前缀
也可以这样写:
- @Component
- public class SysConfiguration {
-
-
- @Bean
- @ConfigurationProperties("wxpay")
- public WxPayBean wxPayBean() {
- return new WxPayBean();
- }
- }
个人觉得这种方式更好,pojo就做最纯正的pojo不写别的
--------------------------------------------------------------------扩展------------------------------------------------------
在application.properties
中的各个参数之间也可以直接引用来使用,就像下面的设置:
- com.didispace.blog.name=圈圈
- com.didispace.blog.title=Spring Boot教程
- com.didispace.blog.desc=${com.didispace.blog.name}正在努力写《${com.didispace.blog.title}》
com.didispace.blog.desc
参数引用了上文中定义的name
和title
属性,最后该属性的值就是程序猿DD正在努力写《Spring Boot教程》
。
在一些情况下,有些参数我们需要希望它不是一个固定的值,比如密钥、服务端口等。Spring Boot的属性配置文件中可以通过${random}
来产生int值、long值或者string字符串,来支持属性的随机值。
- # 随机字符串
- com.didispace.blog.value=${random.value}
- # 随机int
- com.didispace.blog.number=${random.int}
- # 随机long
- com.didispace.blog.bignumber=${random.long}
- # 10以内的随机数
- com.didispace.blog.test1=${random.int(10)}
- # 10-20的随机数
- com.didispace.blog.test2=${random.int[10,20]}
相信使用过一段时间Spring Boot的用户,一定知道这条命令:java -jar xxx.jar --server.port=8888
,通过使用—server.port属性来设置xxx.jar应用的端口为8888。
在命令行运行时,连续的两个减号--
就是对application.properties
中的属性值进行赋值的标识。所以,java -jar xxx.jar --server.port=8888
命令,等价于我们在application.properties
中添加属性server.port=8888
,该设置在样例工程中可见,读者可通过删除该值或使用命令行来设置该值来验证。
通过命令行来修改属性值固然提供了不错的便利性,但是通过命令行就能更改应用运行的参数,那岂不是很不安全?是的,所以Spring Boot也贴心的提供了屏蔽命令行访问属性的设置,只需要这句设置就能屏蔽:SpringApplication.setAddCommandLineProperties(false)
。
我们在开发Spring Boot应用时,通常同一套程序会被应用和安装到几个不同的环境,比如:开发、测试、生产等。其中每个环境的数据库地址、服务器端口等等配置都会不同,如果在为不同环境打包时都要频繁修改配置文件的话,那必将是个非常繁琐且容易发生错误的事。
对于多环境的配置,各种项目构建工具或是框架的基本思路是一致的,通过配置多份不同环境的配置文件,再通过打包命令指定需要打包的内容之后进行区分打包,Spring Boot也不例外,或者说更加简单。
在Spring Boot中多环境配置文件名需要满足application-{profile}.properties
的格式,其中{profile}
对应你的环境标识,比如:
application-dev.properties
:开发环境application-test.properties
:测试环境application-prod.properties
:生产环境
至于哪个具体的配置文件会被加载,需要在application.properties
文件中通过spring.profiles.active
属性来设置,其值对应{profile}
值。
如:spring.profiles.active=test
就会加载application-test.properties
配置文件内容
下面,以不同环境配置不同的服务端口为例,进行样例实验。
针对各环境新建不同的配置文件application-dev.properties
、application-test.properties
、application-prod.properties
在这三个文件均都设置不同的server.port
属性,如:dev环境设置为1111,test环境设置为2222,prod环境设置为3333
application.properties中设置spring.profiles.active=dev
,就是说默认以dev环境设置
测试不同配置的加载
java -jar xxx.jar
,可以观察到服务端口被设置为1111
,也就是默认的开发环境(dev)java -jar xxx.jar --spring.profiles.active=test
,可以观察到服务端口被设置为2222
,也就是测试环境的配置(test)java -jar xxx.jar --spring.profiles.active=prod
,可以观察到服务端口被设置为3333
,也就是生产环境的配置(prod)按照上面的实验,可以如下总结多环境的配置思路:
application.properties
中配置通用内容,并设置spring.profiles.active=dev
,以开发环境为默认配置application-{profile}.properties
中配置各个环境不同的内容在Spring Boot 2.0中推出了Relaxed Binding 2.0,对原有的属性绑定功能做了非常多的改进以帮助我们更容易的在Spring应用中加载和读取配置信息。下面本文就来说说Spring Boot 2.0中对配置的改进。
简单类型
在环境变量中通过小写转换与.
替换_
来映射配置文件中的内容,比如:环境变量SPRING_JPA_DATABASEPLATFORM=mysql
的配置会产生与在配置文件中设置spring.jpa.databaseplatform=mysql
一样的效果。
List类型
由于环境变量中无法使用[
和]
符号,所以使用_
来替代。任何由下划线包围的数字都会被认为是[]
的数组形式。比如:
- MY_FOO_1_ = my.foo[1]
- MY_FOO_1_BAR = my.foo[1].bar
- MY_FOO_1_2_ = my.foo[1][2]
另外,最后环境变量最后是以数字和下划线结尾的话,最后的下划线可以省略,比如上面例子中的第一条和第三条等价于下面的配置:
- MY_FOO_1 = my.foo[1]
- MY_FOO_1_2 = my.foo[1][2]
简单类型
系统属性与文件配置中的类似,都以移除特殊字符并转化小写后实现绑定,比如下面的命令行参数都会实现配置spring.jpa.databaseplatform=mysql
的效果:
- -Dspring.jpa.database-platform=mysql
- -Dspring.jpa.databasePlatform=mysql
- -Dspring.JPA.database_platform=mysql
List类型
系统属性的绑定也与文件属性的绑定类似,通过[]
来标示,比如:
- -D"spring.my-example.url[0]=http://example.com"
- -D"spring.my-example.url[1]=http://spring.io"
同样的,他也支持逗号分割的方式,比如:
-Dspring.my-example.url=http://example.com,http://spring.io
上文介绍了Spring Boot 2.0中对属性绑定的内容,可以看到对于一个属性我们可以有多种不同的表达,但是如果我们要在Spring应用程序的environment中读取属性的时候,每个属性的唯一名称符合如下规则:
.
分离各个元素.
将前缀与属性名称分开-
来分隔单词[
和]
,用于List的索引所以,如果我们要读取配置文件中spring.jpa.database-platform
的配置,可以这样写:
this.environment.containsProperty("spring.jpa.database-platform")
而下面的方式是无法获取到spring.jpa.database-platform
配置内容的:
this.environment.containsProperty("spring.jpa.databasePlatform")
注意:使用@Value
获取配置内容的时候也需要这样的特点
在Spring Boot 2.0中增加了新的绑定API来帮助我们更容易的获取配置信息。下面举个例子来帮助大家更容易的理解:
例子一:简单类型
假设在propertes配置中有这样一个配置:com.didispace.foo=bar
我们为它创建对应的配置类:
- @Data
- @ConfigurationProperties(prefix = "com.didispace")
- public class FooProperties {
-
- private String foo;
-
- }
接下来,通过最新的Binder
就可以这样来拿配置信息了:
- @SpringBootApplication
- public class Application {
-
- public static void main(String[] args) {
- ApplicationContext context = SpringApplication.run(Application.class, args);
-
- Binder binder = Binder.get(context.getEnvironment());
-
- // 绑定简单配置
- FooProperties foo = binder.bind("com.didispace", Bindable.of(FooProperties.class)).get();
- System.out.println(foo.getFoo());
- }
- }
例子二:List类型
如果配置内容是List类型呢?比如:
- com.didispace.post[0]=Why Spring Boot
- com.didispace.post[1]=Why Spring Cloud
-
- com.didispace.posts[0].title=Why Spring Boot
- com.didispace.posts[0].content=It is perfect!
- com.didispace.posts[1].title=Why Spring Cloud
- com.didispace.posts[1].content=It is perfect too!
要获取这些配置依然很简单,可以这样实现:
- ApplicationContext context = SpringApplication.run(Application.class, args);
-
- Binder binder = Binder.get(context.getEnvironment());
-
- // 绑定List配置
- List<String> post = binder.bind("com.didispace.post", Bindable.listOf(String.class)).get();
- System.out.println(post);
-
- List<PostInfo> posts = binder.bind("com.didispace.posts", Bindable.listOf(PostInfo.class)).get();
- System.out.println(posts);
使用占位符:@pom属性@
例:
.yml :
pom:
会根据打包环境获取相应的frofile.name,
SpringBoot四种读取properties文件的方式 SpringBoot四种读取properties文件的方式_猿敲月下码的博客-CSDN博客_springboot 读取properties
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。