springboot之一:配置文件(内外部配置优先顺序+properties、xml、yaml基础语法+profile动态切换配置、激活方式)
作者:mmseoamin日期:2023-12-25

配置的概念:

Spring Boot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用application.properties或者application.yml(application.yaml)进行配置。

注意配置文件的命名必须是application开头。

优先顺序:

在同一级目录下优先级为:properties > yml > yaml

内部配置优先顺序:

  1. file:../config/ :当前项目下的/config目录下直接放的配置文件

  2. file:../config/xxx/:当前项目下的/config目录下的子路径下放的配置文件

  3. file:../ :当前项目的根目录中的配置文件

  4. classpath:/config/:classpath的/config目录的配置文件

  5. classpath:/ :classpath的根目录的配置文件

java和resources的文件会被打包到classes的目录

properties和yml实际上会被打包到classpath路径下

即优先级顺序如图:

springboot之一:配置文件(内外部配置优先顺序+properties、xml、yaml基础语法+profile动态切换配置、激活方式),第1张

外部配置优先顺序:

https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config

properties、xml、yml格式比对:

properties:

server.port=8080
server.address=127.0.0.1

xml:


    8080
    127.0.0.1

yml:

server:
    port:8080
    address:127.0.0.1

Yaml(yml):

  • 大小写有区别
  • 数据前必须有空格(空格数目无所谓)作为分隔符,否则不识别该数据。
  • 缩进的空格数目不重要,但是相同层级的元素要左对齐。
  • 注释的话快捷键也是ctrl+/,是#+空格。
  • 参数引用的话用${}包裹起来即可。

    对象(map):键值对的集合

    person:
        name: zhangsan
    # 行内写法
    person: {name: zhangsan}

    数组

    address:
        - beijing
        - shanghai
    # 行内写法
    address: [beijing,shanghai]

     纯量:单个的、不可再分的值。一般都是字符串

    msg1: 'hello \n world' # 单引忽略转义字符
    msg2: "hello \n world" # 双引识别转义字符

    读取配置内容:

    @Value

    application.yml的对象,用到几个,就要注入几个。

    application.yml中

    server:
      port: 8082
    name: abc
    Person:
      name: zhangsan
      age: 20
    Student:
      name: ${name} # 占位符,表示abc那个name会传输到这里
    address:
      - beijing
      - shanghai
    msg1: 'hello \n world'  # 不会识别转义字符
    msg2: "hello \n world"  # 会识别转义字符

    HelloController中

    package com.example.springini.controller;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    @RestController
    public class HelloController {
        @Value("${name}")
        //和application.yml的键值对的键要同名,与下一行的私有成员名字无关
        private String nname;
        @Value("${Person.name}")
        private String name2;
        @Value("${Person.age}")
        private int age;
        @Value("${Student.name}")
        private String name3;
        @Value("${address[0]}")
        private String addr;
        @Value("${msg1}")
        private String msg11;
        @Value("${msg2}")
        private String msg22;
        @RequestMapping("/hello2")
        public String hello2()
        {
            System.out.println(nname);
            System.out.println(name2);
            System.out.println(name3);
            System.out.println(age);
            return "hello springboot";
        }
        @RequestMapping("/hello")
        public String hello()
        {
            System.out.println(addr);
            System.out.println(msg11);
            System.out.println(msg22);
            return "hello springboot";
        }
    }

    @Autowired+Environment

    将application.yml一次性作为一个对象全都注入。

    HelloController中

    package com.example.springini.controller;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.core.env.Environment;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    @RestController
    public class HelloController_by_environment {
        @Autowired
        private Environment env;
        @RequestMapping("/hello")
        public void hello()
        {
            System.out.println(env.getProperty("name"));
            System.out.println(env.getProperty("Person.name"));
            System.out.println(env.getProperty("address[0]"));
            System.out.println(env.getProperty("msg1"));
            System.out.println(env.getProperty("msg2"));
        }
    }

    @Autowired+ConfigurationProperties

    将配置内容与对象相互绑定。

    新建Person类中

    package com.example.springini;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    @Component  //表示这个Person类被识别成Bean
    @ConfigurationProperties(prefix = "person")
    //如果不指定prefix为person,那么它不一定找到配置文件的person底下的两个字段name和age
    //而可能去找到单独的两个字段name和age。
    public class Person {
        private String name;//命名必须和yml文件中的键值对的键保持一致
        private int age;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    }

    HelloController中

    package com.example.springini.controller;
    import com.example.springini.Person;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.core.env.Environment;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    @RestController
    public class HelloController_by_ConfigurationProperties {
        @Autowired
        private Person p;
        @RequestMapping("/hello")
        public void hello()
        {
            System.out.println(p.getName()+" : "+p.getAge());
        }
    }

    profile(动态配置切换):

    我们在开发Spring Boot应用时,通常同一套程序会被安装到不同环境,比如:开发、测试、生产等。其中数据库地址、服务器端口等等配置都不同,如果每次打包时,都要修改配置文件,那么非常麻烦。profile功能就是来进行动态配置切换的。

    配置方式:

    多profile文件方式