1、配置文件

SpringBoot使用一个全局的配置文件,配置文件名是固定的;

  • application.properties

  • application.yml

配置文件的作用:修改SpringBoot自动配置的默认值;SpringBoot在底层都给我们自动配置好;

标记语言:

  以前的配置文件;大多都使用的是 xxxx.xml文件;

  YAML:以数据为中心,比json、xml等更适合做配置文件;

YAML:配置例子

server:
  port: 8081

 XML:

 <server>
     <port>8081</port>
 </server>

2、YAML语法

2.1 基本语法

  • 键值对(空格必须有)

  • 空格的缩进来控制层级关系

  • 属性和值也是大小写敏感

 server:
     port: 8081
     path: /hello

2.2 值的写法

  1. 字面量:普通的值(数字,字符串,布尔)

    • 字符串默认不用加上单引号或者双引号

  2. 对象、Map(属性和值)(键值对)

    • 在下一行来写对象的属性和值的关系

       friends:
          lastName: zhangsan
          age: 20

      行内写法:

       friends: {lastName: zhangsan,age: 18}
  3. 数组(List、Set)

    • 用- 值表示数组中的一个元素

       pets:
        - cat
        - dog
        - pig

      行内写法

       pets: [cat,dog,pig]

3、配置文件值注入

配置文件 yml

 person:
     lastName: hello
     age: 18
     boss: false
     birth: 2017/12/12
     maps: {k1: v1,k2: 12}
     lists:
       - lisi
       - zhaoliu
     dog:
       name: 小狗
       age: 12

配置文件 properties

 person.lastName=hello
 person.age=18
 person.boss=false
 person.birth=2017/12/12
 person.maps={k1: v1,k2: 12}
 person.lists=[lisi,zhaoliu]
 person.dog.name=小狗
 person.dog.age=6

3.1 @ConfigurationProperties

编写javaBean

/**
  * 将配置文件中的配置的每一个属性值,映射到组件中
  * @ConfigurationProperties: 告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定。
  *      prefix: 配置文件中的prefix指定的属性下的所有属性与该组件属性一一对应。
  *
  * @ConfigurationProperties: 默认从全局配置文件中获取值
  *
  * 只有这个组件是容器中的组件,容器才能提供@ConfigurationProperties功能。
  */
 @Data
 @Component
 @ConfigurationProperties(prefix = "person")
 public class Person1 {
 ​
     private String lastName;
     private Integer age;
     private Boolean boss;
     private Date birth;
 ​
     private Map<String,Object> maps;
     private List<Object> lists;
     private Dog dog;
 ​
 }
 ​
 // ------------------------------------------------------------------------
 /**
 * @PropertySource:加载指定的配置文件;
 */
 @Data
 @Component
 @PropertySource(value = {"classpath:person.properties"})
 @ConfigurationProperties(prefix = "person")
 public class Person2 {
 ​
     private String lastName;
     private Integer age;
     private Boolean boss;
     private Date birth;
 ​
     private Map<String,Object> maps;
     private List<Object> lists;
     private Dog dog;
 ​
 }
  1. 我们可以导入配置文件处理器,以后编写配置就有提示了

     <!--导入配置文件处理器,配置文件进行绑定就会有提示-->
             <dependency>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-configuration-processor</artifactId>
                 <optional>true</optional>
             </dependency>

     

  2. properties配置文件在idea中默认utf-8可能会乱码

    • 尝试在application.properties中添加配置:

       spring.http.encoding.force=true
       spring.http.encoding.charset=UTF-8
       spring.http.encoding.enabled=true
       server.tomcat.uri-encoding=UTF-8

       

    • 设置 File Encodings的Transparent native-to-ascii conversion为true,具体步骤如下:

      • File -> Settings -> Editor -> File Encodings

      • 将页面顶端的Global Encoding和Project Encoding置为UTF-8

      • 将Properties Files (*.properties)下的Default encoding for properties files设置为UTF-8

      • 将Transparent native-to-ascii conversion前的勾选上

3.2 @Value

application.properties

 book.name=SpringCloudInAction
 book.author=ZhaiYongchao

然后,在应用中我们可以通过@Value注解来加载这些自定义的参数,比如:

@Component
public class Book {    
    @Value("${book.name}")    
    private String name;    
    @Value("${book.author}")    
    private String author;    
    // 省略getter和setter
}

@Value注解加载属性值的时候可以支持两种表达式来进行配置:

  • 一种是我们上面介绍的PlaceHolder方式,格式为 ${...},大括号内为PlaceHolder

  • 另外还可以使用SpEL表达式(Spring Expression Language), 格式为 #{...},大括号内为SpEL表达式

目前这2种是比较常用的


4、配置文件占位符

4.1 随机数

 ${random.value}、${random.int}、${random.long}
 ${random.int(10)}、${random.int[1024,65536]}

4.2 占位符获取之前配置的值,如果没有可以是用:指定默认值

 person.last-name=张三${random.uuid}
 person.age=${random.int}
 person.birth=2017/12/15
 person.boss=false
 person.maps.k1=v1
 person.maps.k2=14
 person.lists=a,b,c
 person.dog.name=${person.hello:hello}_dog
 person.dog.age=15

5、命令行参数

java -jar xxx.jar --server.port=8888,直接以命令行的方式,来设置server.port属性,另启动应用的端口设为8888。

在命令行方式启动Spring Boot应用时,连续的两个减号--就是对application.properties中的属性值进行赋值的标识。所以,java -jar xxx.jar --server.port=8888命令,等价于我们在application.properties中添加属性server.port=8888


6、多环境配置

在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中配置各个环境不同的内容

  • 通过命令行方式去激活不同环境的配置


7、加载顺序

Spring Boot为了能够更合理的重写各属性的值,使用了下面这种较为特别的属性加载顺序:

  1. 命令行中传入的参数。

  2. SPRING_APPLICATION_JSON中的属性。SPRING_APPLICATION_JSON是以JSON格式配置在系统环境变量中的内容。

  3. java:comp/env中的JNDI属性。

  4. Java的系统属性,可以通过System.getProperties()获得的内容。

  5. 操作系统的环境变量

  6. 通过random.*配置的随机属性

  7. 位于当前应用jar包之外,针对不同{profile}环境的配置文件内容,例如:application-{profile}.properties或是YAML定义的配置文件

  8. 位于当前应用jar包之内,针对不同{profile}环境的配置文件内容,例如:application-{profile}.properties或是YAML定义的配置文件

  9. 位于当前应用jar包之外的application.propertiesYAML配置内容

  10. 位于当前应用jar包之内的application.propertiesYAML配置内容

  11. @Configuration注解修改的类中,通过@PropertySource注解定义的属性

  12. 应用默认属性,使用SpringApplication.setDefaultProperties定义的内容

优先级按上面的顺序有高到低,数字越小优先级越高。