当前位置:   article > 正文

spring boot 自定义配置文件&参数绑定(application.properties配置|application.yaml配置)

spring boot 自定义配置文件&参数绑定(application.properties配置|application.yaml配置)

SpringBoot配置文件类型和作用

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种配置方式都是等价的:

  • properties格式:
  1. spring.jpa.databaseplatform=mysql
  2. spring.jpa.database-platform=mysql
  3. spring.jpa.databasePlatform=mysql
  4. spring.JPA.database_platform=mysql
  • yaml格式:
  1. spring:
  2. jpa:
  3. databaseplatform: mysql #行注释
  4. database-platform: mysql
  5. databasePlatform: mysql
  6. database_platform: mysql

注意:

  • key与value之间的存在一个空格 
  • 配置可以使用驼峰式也可以使用-分隔符,推荐使用全小写配合-分隔符的方式来配置,比如:spring.jpa.database-platform=mysql
  • 行注释#前面有个空格

List(set,数组)类型

在properties文件中使用[]来定位列表类型,比如:

  1. student.name[0]=孙悟空
  2. student.name[1]=张三丰

也支持使用逗号分割的配置方式,上面与下面的配置是等价的:

student.name=孙悟空,张三丰

而在yaml文件中使用可以使用如下配置:

  1. student:
  2. name:
  3. - 孙悟空
  4. - 张三丰

注意 - 后有空格  出现关机字可以用""括起来

也支持逗号分割的方式:

  1. student:
  2. name: 孙悟空, 张三丰

或者

  1. student:
  2. name: [孙悟空, 张三丰]

集合中的元素是对象(或map)形式:

  1. student:
  2. - name: zhangsan
  3. age: 18
  4. score: 100
  5. - name: lisi
  6. age: 28
  7. score: 88
  8. - name: wangwu
  9. age: 38
  10. 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(对象)类型

Map类型在properties和yaml中的标准配置方式如下:

  • properties格式:
  1. spring.my-example.foo=bar
  2. spring.my-example.hello=world
  • yaml格式:
  1. spring:
  2. my-example:
  3. foo: bar
  4. hello: world

注意:如果Map类型的key包含非字母数字和-的字符,需要用[]括起来,比如:

  1. spring:
  2. my-example:
  3. '[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

其中,key1key2Map中的键,你可以根据需要添加更多的键值对。

Java 代码这样写: 

  1. import org.springframework.boot.context.properties.ConfigurationProperties;
  2. import org.springframework.stereotype.Component;
  3. import java.util.Map;
  4. @Component
  5. @ConfigurationProperties(prefix = "myapp")
  6. public class MyAppProperties {
  7. private Map<String, Task> taskProperties;
  8. public Map<String, Task> getTaskProperties() {
  9. return taskProperties;
  10. }
  11. public void setTaskProperties(Map<String, Task> taskProperties) {
  12. this.taskProperties = taskProperties;
  13. }
  14. public static class Task {
  15. private String target;
  16. private int threadCount;
  17. }
  18. }

配置文件与配置类的属性映射方式

使用注解@Value映射:

application.properties配置:

person.name=zhangsan
person.age=18

或者,application.yml配置:

person:
  name: zhangsan
  age: 18

  • 然后通过@Value("${属性名}")注解来加载对应的配置属性:

  1. @Controller
  2. public class QuickStartController {
  3. @Value("${person.name}")
  4. private String name;
  5. //设置默认值,person.name:是空值
  6. @Value("${person.name:王大拿}")
  7. private String name2;
  8. @Value("${person.age}")
  9. private Integer age;
  10. @RequestMapping("/quick")
  11. @ResponseBody
  12. public String quick(){
  13. return "springboot 访问成功! name="+name+",age="+age;
  14. }
  15. }

使用@Value注入map、List稍微复杂

配置文件

  1. list: topic1,topic2,topic3
  2. maps: "{key1: 'value1', key2: 'value2'}
  3. maps2: "{key1: '[value1,value2]', key2: '[value1,value2]'}

实体类

  1. @Value("#{'${list}'.split(',')}")
  2. private List<String> list;
  3.  
  4. @Value("#{${maps}}")  
  5. private Map<String,String> maps;
  6. @Value("#{${maps}}")  
  7. private Map<String,List<String>> maps;


 

  • 使用注解@ConfigurationProperties映射对象(配置文件与对象绑定)

通过注解@ConfigurationProperties(prefix="配置文件中的key的前缀,可以使properties文件也可以是yml文件")可以将配置文件中的配置自动与实体进行映射(这个注解能作用在类上也能作用在方法上)

实体Bean代码如下:
 

  1. @Controller
  2. //@PropertySource("classpath:/production/wxpay.properties") //的值是配置文件文件的路径
  3. @ConfigurationProperties(prefix = "person")//配置文件前缀
  4. public class QuickStartController {
  5. private String name;
  6. private Integer age;
  7. @RequestMapping("/quick")
  8. @ResponseBody
  9. public String quick(){
  10. return "springboot 访问成功! name="+name+",age="+age;
  11. }
  12. public void setName(String name) {
  13. this.name = name;
  14. }
  15. public void setAge(Integer age) {
  16. this.age = age;
  17. }
  18. }

注意:使用@ConfigurationProperties方式可以进行配置文件与实体字段的自动映射,但需要字段必须提供set方法才可以,而使用@Value注解修饰的字段不需要提供set方法
 

@PropertySource("classpath:/production/wxpay.properties") 的值是properties文件的路径,如果是默认配置文件可以不写此注解
@ConfigurationProperties(prefix = "wxpay") prefix属性值是配置文件key的前缀

也可以这样写:

  1. @Component
  2. public class SysConfiguration {
  3. @Bean
  4. @ConfigurationProperties("wxpay")
  5. public WxPayBean wxPayBean() {
  6. return new WxPayBean();
  7. }
  8. }

个人觉得这种方式更好,pojo就做最纯正的pojo不写别的

--------------------------------------------------------------------扩展------------------------------------------------------

参数间的引用

application.properties中的各个参数之间也可以直接引用来使用,就像下面的设置:

  1. com.didispace.blog.name=圈圈
  2. com.didispace.blog.title=Spring Boot教程
  3. com.didispace.blog.desc=${com.didispace.blog.name}正在努力写《${com.didispace.blog.title}》

com.didispace.blog.desc参数引用了上文中定义的nametitle属性,最后该属性的值就是程序猿DD正在努力写《Spring Boot教程》

使用随机数

在一些情况下,有些参数我们需要希望它不是一个固定的值,比如密钥、服务端口等。Spring Boot的属性配置文件中可以通过${random}来产生int值、long值或者string字符串,来支持属性的随机值。

  1. # 随机字符串
  2. com.didispace.blog.value=${random.value}
  3. # 随机int
  4. com.didispace.blog.number=${random.int}
  5. # 随机long
  6. com.didispace.blog.bignumber=${random.long}
  7. # 10以内的随机数
  8. com.didispace.blog.test1=${random.int(10)}
  9. # 10-20的随机数
  10. 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.propertiesapplication-test.propertiesapplication-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类型

由于环境变量中无法使用[]符号,所以使用_来替代。任何由下划线包围的数字都会被认为是[]的数组形式。比如:

  1. MY_FOO_1_ = my.foo[1]
  2. MY_FOO_1_BAR = my.foo[1].bar
  3. MY_FOO_1_2_ = my.foo[1][2]

另外,最后环境变量最后是以数字和下划线结尾的话,最后的下划线可以省略,比如上面例子中的第一条和第三条等价于下面的配置:

  1. MY_FOO_1 = my.foo[1]
  2. MY_FOO_1_2 = my.foo[1][2]

系统属性绑定

简单类型

系统属性与文件配置中的类似,都以移除特殊字符并转化小写后实现绑定,比如下面的命令行参数都会实现配置spring.jpa.databaseplatform=mysql的效果:

  1. -Dspring.jpa.database-platform=mysql
  2. -Dspring.jpa.databasePlatform=mysql
  3. -Dspring.JPA.database_platform=mysql

List类型

系统属性的绑定也与文件属性的绑定类似,通过[]来标示,比如:

  1. -D"spring.my-example.url[0]=http://example.com"
  2. -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中读取属性的时候,每个属性的唯一名称符合如下规则:

  • 通过.分离各个元素
  • 最后一个.将前缀与属性名称分开
  • 必须是字母(a-z)和数字(0-9)
  • 必须是小写字母
  • 用连字符-来分隔单词
  • 唯一允许的其他字符是[],用于List的索引
  • 不能以数字开头

所以,如果我们要读取配置文件中spring.jpa.database-platform的配置,可以这样写:

this.environment.containsProperty("spring.jpa.database-platform")

而下面的方式是无法获取到spring.jpa.database-platform配置内容的:

this.environment.containsProperty("spring.jpa.databasePlatform")

注意:使用@Value获取配置内容的时候也需要这样的特点

全新的绑定API

在Spring Boot 2.0中增加了新的绑定API来帮助我们更容易的获取配置信息。下面举个例子来帮助大家更容易的理解:

例子一:简单类型

假设在propertes配置中有这样一个配置:com.didispace.foo=bar

我们为它创建对应的配置类:

  1. @Data
  2. @ConfigurationProperties(prefix = "com.didispace")
  3. public class FooProperties {
  4. private String foo;
  5. }

接下来,通过最新的Binder就可以这样来拿配置信息了:

  1. @SpringBootApplication
  2. public class Application {
  3. public static void main(String[] args) {
  4. ApplicationContext context = SpringApplication.run(Application.class, args);
  5. Binder binder = Binder.get(context.getEnvironment());
  6. // 绑定简单配置
  7. FooProperties foo = binder.bind("com.didispace", Bindable.of(FooProperties.class)).get();
  8. System.out.println(foo.getFoo());
  9. }
  10. }

例子二:List类型

如果配置内容是List类型呢?比如:

  1. com.didispace.post[0]=Why Spring Boot
  2. com.didispace.post[1]=Why Spring Cloud
  3. com.didispace.posts[0].title=Why Spring Boot
  4. com.didispace.posts[0].content=It is perfect!
  5. com.didispace.posts[1].title=Why Spring Cloud
  6. com.didispace.posts[1].content=It is perfect too!

要获取这些配置依然很简单,可以这样实现:

  1. ApplicationContext context = SpringApplication.run(Application.class, args);
  2. Binder binder = Binder.get(context.getEnvironment());
  3. // 绑定List配置
  4. List<String> post = binder.bind("com.didispace.post", Bindable.listOf(String.class)).get();
  5. System.out.println(post);
  6. List<PostInfo> posts = binder.bind("com.didispace.posts", Bindable.listOf(PostInfo.class)).get();
  7. System.out.println(posts);

从pom.xml 中读取数据

使用占位符:@pom属性@

例:

.yml :

pom:

会根据打包环境获取相应的frofile.name,

SpringBoot四种读取properties文件的方式 SpringBoot四种读取properties文件的方式_猿敲月下码的博客-CSDN博客_springboot 读取properties

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号