SpringBoot配置文件(三)

SpringBoot使用一个全局的配置文件,配置文件名application是固定的;
有以下三种文件后缀是配置文件

yaml和properties配置文件同时存在,properties配置文件的内容会覆盖yaml配置文件的内容

application.properties
application.yml
application.yaml

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

为了更好的编写配置文件,可以使用yaml来编写,yml和yaml后缀的文件都是使用yaml来编辑的

一、YAML(如果懂得可以略过这里)

YAML全名:YAML Ain't Markup Language

​ YAML A Markup Language:是一个标记语言

​ YAML isn't Markup Language:不是一个标记语言;

标记语言:

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

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

YAML语法

1.以空格的缩进来控制层级关系;只要是左对齐的一列数据,都是同一个层级的
2.次等级的前面必须是空格,不能使用制表符(tab)来代替空格
3.冒号之后如果有值,那么冒号和值之间至少有一个空格,不能紧贴着


image.png

1.各种值的写法

字面量:指的是(数字,字符串,布尔)

k: y
字符串默认不用加上单引号或者双引号;

  1. " ":双引号;不会转义字符串里面的特殊字符;特殊字符会作为本身想表示的意思
    name: "测试1 \n 测试2":
    输出:测试1 (换行再输出) 测试2
  2. ' ':单引号;会转义特殊字符,特殊字符最终只是一个普通的字符串数据
    name: "测试1 \n 测试2":
    输出:测试1 \n 测试2
对象、Map(属性和值):

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

//第一种写法
person:
  name: 张三
  gender: 男
  age: 22
//第二种写法
person: {name: 张三,gender: 男,age: 22}

数组(List,Set):

第一个值表示数组中的第一个值

//第一种写法
fruits: 
  - 苹果
  - 桃子
  - 香蕉
//第二种写法
fruits: [苹果,桃子,香蕉]

二、配置文件值的注入

在pom文件中插入以下代码,然后运行项目之后会在配置文件编写的时候有提示

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

1.编写配置文件

//YAML的写法
person:
  name: 张三
  gender: 男
  age: 36
  boss: true
  birth: 1982/10/1
  maps: {k1: v1,k2: v2}
  lists:
    - apple
    - peach
    - banana
  dog:
    name: 小狗


//properties配置文件的写法
person.name=李四
person.age=34
person.birth=1986/09/12
person.boss=true
person.gender=女
person.lists=cat,dog,pig
person.maps.k1=v1
person.maps.k2=v2
person.dog.name="小黑"

这里需要注意的是,配置文件所对应的bean文件必须在主程序类的同一包下
image.png

2.编写Person文件(并添加上get,set,tostring方法)

  • @ConfigurationProperties

  • 将配置文件的每一个属性值映射到这个组件中,

  • 告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定

  • prefix = "person" :配置文件中哪个下面的所有属性映射到本类中

  • 而这个组件必须是容器中的组件,才能使用容器提供的@ConfigurationProperties功能

  • 所以必须加上@Component注解,

  • 即这两个注解是搭配使用的

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

    private String name;
    private Integer age;
    private Boolean boss;
    private Date birth;

    private Map<String,Object> map;
    private List<Object> list;
    private Dog dog;

3.测试

package cn.clboy.helloworldquickstart;

import cn.clboy.helloworldquickstart.model.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class HelloworldquickstartApplicationTests {

    @Autowired
    private Person person;

    @Test
    void contextLoads() {
        System.out.println(person);
    }

}

结果1

测试用YAML配置文件写法的结果如下


image.png

结果2

测试中用properties配置文件的写法会出现中文会乱码,而且char类型还会抛出Failed to bind properties under 'person.gender' to java.lang.Character异常


image.png

中文乱码解决方法

在设置中找到File Encodings,将配置文件字符集改为UTF-8,并勾选:Transparent native-to-ascii conversion


英文版
中文版

三、配置文件值注入两种方式对比

配置文件值注入有两种方式:
一个是上面提到的Spring Boot的@ConfigurationProperties注解
一个是spring原先的@value注解

两种功能的比较


image.png

松散绑定:例如Person中有lastName属性,在配置文件中可以写成 lastName 或 lastname 或 last-name 或
last_name 等

SpEL:

## properties配置文件
persion.age=#{2019-1986+1}

------------------------------------------分割线---------------------------------------

# Person类
#--------------------使用@ConfigurationProperties注解,会抛出异常--------------------
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private Integer age;

#--------------------使用@value注解,没有问题--------------------
@Component
public class Person {
    @Value("${person.age}")
    private Integer age;

JSR303数据校验

@ConfigurationProperties支持校验,如果校验不通过,会抛出异常
image.png

@value注解不支持数据校验
image.png

复杂类型封装

@value注解无法注入map等对象的复杂类型,但list、数组可以
image.png

两种方式小结:

如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,就使用@Value
如果说,我们专门编写了一个javaBean来和配置文件进行映射,就使用@ConfigurationProperties

四、注解解析

1、@PropertySource

注解的作用是加载指定的配置文件,值可以是数组,也就是可以加载多个配置文件

springboot默认加载的配置文件名是application,如果配置文件名不是这个是不会被容器加载的,所以这里Person并没有被注入任何属性值
image.png

使用@PropertySource({"classpath:person.properties"})指定加载person.properties配置文件
需要指定加载多个配置文件时{"classpath:person.properties","classpath:person.properties"}

image.png

使用这个注解加载配置文件就需要配置类使用@component等注解而不是等待@EnableConfigurationProperties激活,而且不支持yaml,只能是properties

2、@ImportResource

@ImportResource:用于导入Spring的配置文件,让配置文件里面的内容生效;(就是以前写的springmvc.xml、applicationContext.xml)

Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;
image.png

想让自己写的Spring的配置文件生效加载进来;就需要吧@ImportResource标注在一个配置类上
image.png

3、@Configuration

这是SpringBoot推荐给容器中添加组件的方式;推荐使用全注解的方式

配置类@Configuration ---等于---> Spring配置文件

3.1 @Bean

/***
 * @Configuration
 * 指明当前类是一个配置类;就是用来代替之前的Spring配置文件
 * Spring配置文件中是用<bean></bean>标签来添加组件
 * 而这里只需要用 @Bean
 */
@Configuration
public class MyAppConfig {

    //将方法返回的值添加到容器中;容器中这个组件默认id就是方法名
    @Bean
    public HelloService helloService(){
        System.out.println("配置类给容器中添加组件");
        return new HelloService();
    }
}

四、配置文件的占位符

随机的占位符
${random.value}
${random.int}
${random.long}
${random.int(10)}
${random.int[1024,65536]}
效果图

可以引用在配置文件中配置的其他属性的值,如果使用一个没有在配置文件中的属性,则会原样输出


配置文件中无此配置

可以使用 : 指定默认值,如果没有该属性则使用默认值


占位符默认值

五、Profile

Profile是Spring对不同环境提供不同配置功能的支持,可以通过激活、指定参数等方式快速切换环境

1、多profile文件形式

文件名格式:application-{profile}.properties/yml,例如:

application-dev.properties
application-prod.properties


样例

程序启动时会默认加载application.properties,启动的端口就是8080,可以在主配置文件中指定激活哪个配置文件
激活dev环境配置
2、yml支持多文档块方式

每个文档块使用---分割

server:
  port: 8080
spring:
  profiles:
    active: prod
---
server:
  port: 8081
spring:
  profiles: dev
---
server:
  port: 8082
spring:
  profiles: prod
image.png
3、激活指定profile的三种方式

1、在配置文件中指定 spring.profiles.active=dev(如上)
2、项目打包后在用命令行启动时,在其命令后面带上 --spring.profiles.active=dev 即可

java -jar xxxxxxxxx.jar --spring.profiles.active=dev


启动对比图

3、配置虚拟机参数

-Dspring.profiles.active=dev


image.png
image.png
4、配置文件加载位置

一级(当前项目文件路径下的config文件夹下) :file: ./config/

二级( 当前项目文件路径下):​ file: ./

三级( 类路径下的config文件夹):​ classpath: /config/

四级(类路径下):​ classpath: /

优先级由高到底,高优先级的配置会覆盖低优先级的配置;(优先级低的先加载,后续会被优先级高的覆盖互补);
SpringBoot会从这四个位置全部加载主配置文件;并互补配置!!

image.png

这里需要注意的是,项目根路径下的配置文件在maven编译时不会打包过去,需要在pom的build标签中增加以下代码

        <resources>
            <resource>
                <directory>.</directory>
                <filtering>true</filtering>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.yaml</include>
                </includes>
            </resource>
        </resources>

此外还可以通过spring.config.location来改变默认的配置文件位置,(该指定的配置优先级最高)
项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用形成互补配置;

java -jar xxx.jar --spring.config.location=D:/home/cloudlandboy/application.yaml

6、外部配置加载循序

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

  1. 命令行参数

    所有的配置都可以在命令行上进行指定,多个配置用空格分开; --配置项=值

    java -jar xxx.jar --server.port=8087  --server.context-path=/abc
    

2.来自java:comp/env的JNDI属性

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

  2. 操作系统环境变量

  3. RandomValuePropertySource配置的random.*属性值

优先加载带profile(由jar包从外向内进行寻找)

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

再来加载不带profile(由jar包从外向内进行寻找)

  1. jar包外部的application.propertiesapplication.yml(不带spring.profile)配置文件
  2. jar包内部的application.propertiesapplication.yml(不带spring.profile)配置文件
image.png
  1. @Configuration注解类上的@PropertySource
  2. 通过SpringApplication.setDefaultProperties指定的默认属性

所有支持的配置加载来源均可查考官方文档:官方文档

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容