SpringBoot 配置文件

1. 前言

       SpringBoot 自动配置源码分析

       在上一篇博客中,我们分析了SpringBoot自动配置的原理。通过自动配置,其会依照我们搭建项目时给予的组件之间依赖性为我们自动配置好了组件能正常启动相关的配置,我们直接启动即可,因为设置的是默认值,当一些业务情况需要更改配置默认值时,SpringBoot也提供了解决方案,那就是提供配置文件让我们修改默认值,SpringBoot会将配置文件中配置的属性值设置为组件相应的配置值。

2. SpringBoot 配置文件的种类

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

  • application.properties
  • application.yml

       properties文件格式的配置文件,在使用快速向导创建SpringBoot应用的时候,默认就在resources目录下创建了,因此它是默认的全局配置文件,这种配置文件语法是“key=value”的形式;

       properties:配置示例

server.port=8081

       YAMLYAML Ain’t Markup Language)语言的文件,文件语法使用空白,缩进,分行组织数据,yml文件采取树状结构,更加简洁易读,以数据为中心,比jsonxml等更适合做配置文件。

       YAML:配置示例

server:
  port: 8081

       XML:配置示例

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

3. 两种配置文件的区别

3.1 内容格式比较

       properties文件语法是“key=value”的形式,对于复杂属性数据,是以“.”号连接层级关系的。结构上没有分层效果;
       而yml文件采用树状结构,结构上有明显的分层效果,语法是以"key:(空格)value"的形式,以空间的缩进来控制层级关系,只要是左对齐的一列数据,都是属性同一层级的。

3.2 执行顺序

       工程中同时存在application.properties文件和 application.yml文件,yml文件会先加载,而后加载的properties文件会覆盖yml文件。所以建议工程中,只使用其中一种类型的文件即可。

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
       可以看到,propertiesyml文件采用不同的端口,最终是以properties文件的内容为准。

4. YML 语法

4.1 基本语法

       key:(空格)value: 表示一对键值对(空格必须有)

       以空格的缩进来控制层级关系、只要是左对齐的一列数据,都是同一个层级的。

server:
	port: 8081
	path: /hello

       属性和值也是大小写敏感的。

4.2 值的写法

4.2.1 字面量: 普通的值(数字、字符串、布尔)

       key: value: 字面量

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

       "":双引号 ;不会转义字符里面的特殊字符;特殊字符会作为本身想表示的意思。

              name: "zhangsan \n lisi", 输出: zhangsan 换行 lisi

       '':单引号 ;会转义字符里面的特殊字符;特殊字符最终只是一个普通的字符串数据

              name: 'zhangsan \n lisi' 输出:zhangsan \n lisi

4.2.2 对象、Map(属性和值)(键值对)

       key: value: 在下一行来写对象的属性和值的关系;注意缩进

       对象还是key: value: 值的方式。

friends:
	lastName: zhangsan
	age: 20

       行内写法:

friends: {lastName: zhangsan,age: 18}

4.2.3 数组(List、Set)

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

pets:
	- cat
	- dog
	- pig

       行内写法:

pets: [cat,dog,pig]

5. 两种配置文件获取值的方式

       配置文件内容

person:
  lastName: zhangsan
  age: 18
  boss: false
  birth: 2018/1/1
  maps: {k1: v1 ,k2: v2}
  lists:
    - lisi
    - wangwu
  dog:
    name: xiaogou
    age: 3

5.1 通过 @ConfigurationProperties 注解

       @ConfigurationProperties注解作用是告诉SpringBoot将本类中的所有属性与配置文件中的属性进行绑定,它需要提供prefix属性,可通过统一前缀批量将类中属性和配置文件中属性进行绑定,使用该方式的时候需要引入配置文件处理器依赖:

	<dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-configuration-processor</artifactId>
         <optional>true</optional>
     </dependency>

       并且使用添加@Component@Configuration或者@EnableConfigurationProperties注解,将类作为容器中的组件,才能使用容器中的功能。

       示例代码如下:

package com.example.demo.entity;

import org.springframework.stereotype.Component;

@Component
@Data
public class Dog {

    private String name;

    private int age;

}

5.1.1 使用@Component注解

package com.example.demo.entity;


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@Component
@ConfigurationProperties(prefix = "person")
@Data
public class Person {

    private Map<String,Object> maps;

    private List<Object> lists;

    private Dog dog;
}

5.1.2 使用 @configuration 注解

package com.example.demo.entity;


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@configuration
@ConfigurationProperties(prefix = "person")
@Data
public class Person {

    private Map<String,Object> maps;

    private List<Object> lists;

    private Dog dog;
}

5.1.3 使用 @EnableConfigurationProperties 注解

package com.example.demo.entity;


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@ConfigurationProperties(prefix = "person")
@Data
public class Person {

    private Map<String,Object> maps;

    private List<Object> lists;

    private Dog dog;
}
@SpringBootApplication
@EnableConfigurationProperties(Person.class)
public class DemoApplication {

    @Autowired
    private Person person;

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    @ResponseBody
    public String hello() {
        System.out.println("person" + person);
        return "hello world";
    }

    public static void main(String[] args) {
        //SpringApplication.run(TestProperty1.class, args);
        new SpringApplicationBuilder(DemoApplication.class).web(SERVLET).run(args);

    }
}

5.2 通过 @Value 注解

       @Value注解类似在原始Spring项目在配置文件中配置bean标签,在bean标签中配置了properties标签,并提供value属性值,例如:

<bean class="xxx">
  <properties name="xxx" value=""/>
</bean>

@Value注解相当于这个properties标签中的value属性值。

       使用@Value注解不能通过前缀批量将类中所有属性与配置文件中特定属性绑定,它支持使用${key}(从环境变量、配置文件中获取值)、#{SpEl}等。

       比如:

    @Value("${person.last-name}")
    private String name;

    @Value("#{11*2}")  
    private int age;

    @Value("true")
    private boolean flag;

       将配置文件中的属性绑定到类中的属性时,对于对象属性,如果键包含除小写字母数字字符或-以外的任何字符,则需要使用括号表示法,以便保留原始值。如果键未被[]包围,则将删除任何非字母数字或-的字符。比如map属性:

#yml文件写法
#自定义map集合
person:
  maps:
    "[/key1]": value1
    /key3: value3
    k2: v2


#properties文件写法
#自定义map集合
person.maps.[/key1]=va2
person.maps./key3=v2

那么使用注解获取到的map集合内容为maps={/key1=va2, key3=v2}

5.3 @ConfigurationProperties 和 @Value 注解不同

在这里插入图片描述

5.3.1 松散绑定

       比如类中定义了一个属性,属性名为firstName,如果使用@ConfigurationProperties,那么配置文件中,该属性可以写成如下形式:

person.firstName:使用标准方式
person.first-name:大写用-,建议在.properties和.yml文件中使用。
person.first_name:大写用_,它是用于.properties和.yml文件的可选格式。
PERSON.FIRST_NAME  大写格式,建议在使用系统环境变量时使用。

       但是如果使用@Value注解,那么只能写成@Value("${person.firstName}")

       每个属性源的宽松绑定规则

在这里插入图片描述

5.3.2 JSR303 数据校验

       @ConfigurationProperties注解支持JSR303数据校验,意味着进行数据校验的属性必须符合规则才给予通过,否则报错。比如给类中的某个属性添加@Email注解,则规定,该属性值必须符合邮箱格式才进行通过。查看代码:

@Validated
public class Person {

    @Value("${person.last-name}")
    @Email
    private String name;

}

5.3.3 关于绑定类中的属性是否需要提供set、get方法

       这个情况只适应于使用@ConfigurationProperties注解。由于绑定是通过标准javaBean属性,因此绝大情况下属性都需要提供settergetter方法,除以下情况可以省略setter方法:

  • 集合或者数组可以通过索引(通常使用yaml)或使用单个逗号分隔值(属性)访问。对于数组属性,setter方法是强制的。我们建议始终为此类类型添加setter方法。如果初始化集合,请确保它不是不可变的。
  • 初始化了嵌套的POJO属性,例如:person类中有一个属性:private Dog dog=new Dog();则不需要setter方法,但是是private Dog dog;则需要提供setter方法。如果希望绑定器使用其默认构造函数动态创建实例,则需要一个setter方法
  • 最后,只考虑标准的JavaBean属性,不支持对静态属性的绑定

6. 配置文件占位符

       SpringBoot配置文件中允许使用随机数或者在配置文件中引用前面配置过的属性来作为占位符。

       比如使用随机数的占位符:

${random.int}
${random.long}
${random.value}
${random.uuid}
${random.int(10)}
${random.int[1024,65523]}

       比如在文件中引用前面配置过的属性作为占位符:

app.name=MyApp
app.decription=${app.name} is a SpringBoot Application

        如果配置文件上下文没有该属性时,我们随便输入一个属性名,那么它将会把这个属性名打印出来,比如:

app.name=Myapp
app.decription=${MyProject} is a SpringBoot Application

       那么使用注解获取app.decription这个属性值时,打印的结果为:MyProject is a SpringBoot Application

       我们还可以为这个配置文件上下文都没有的属性值赋值。比如如下操作:

app.name=Myapp
app.decription=${MyProject:customProject} is a SpringBoot Application

       那么使用注解获取app.decription这个属性值时,打印的结果为:customProject is a SpringBoot Application

7. profile

7.1多 Profile 文件

       我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml

       默认使用application.properties

在这里插入图片描述

7.2 yml 支持多文档块方式


server:
  port: 8081
spring:
  profiles:
    active: dev
---

server:
  port: 8082
spring:
  profiles: dev

---

server:
  port: 8083
spring:
  profiles: prod

7.3 激活指定 Profile

  1. 在配置文件中指定 spring.profiles.active=dev

  2. 命令行:--spring.profiles.active=dev

在这里插入图片描述

  1. 虚拟机参数:-Dspring.profiles.active=dev

在这里插入图片描述

8. 配置文件加载位置

       SpringBoot启动会扫描以下位置的application.properties或者application.yml文件作为SpringBoot的默认配置文件

  • file:./config/
  • file:./
  • classpath:/config/
  • classpath:/

       以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置内容。

       我们也可以通过配置spring.config.location来改变默认配置。

       Spring Boot会从这四个位置全部加载主配置文件;互补配置

       我们也可以通过spring.config.location来改变默认配置

       项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件一起生效。

9. 外部配置加载顺序

       SpringBoot也可以从以下位置加载配置,优先级从高到低。高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置。

  1. 命令行参数

       java -jar spring-boot-04-config-0.0.1-SNAPSHOT.jar --server.port=8087 --server.context-path=/abc

       多个配置项空格分隔,写法:--配置项=值

  1. 来自java:comp/envJNDI属性

  2. Java系统属性( System.getProperties() )

  3. 操作系统环境变量

  4. RandomValuePorpertySource配置的random.*属性值

       由jar包外向jar包内进行寻找

       优先加载带profile

  1. jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件

  2. jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件

       再来加载不带profile

  1. jar包外部的application-{profile}.properties或application.yml(不带spring.profile)配置文件

  2. jar包内部的application-{profile}.properties或application.yml(不带spring.profile)配置文件

  3. @Configuration注解类上的@PropertySource

  4. 通过SpringApplication.setDefaultProperties指定默认属性

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值