Loading

36-配置文件

1. yml 配置文件

SpringBoot 使用一个全局的配置文件,配置文件名是固定的(如下),位置在 src/main/resources 目录或者类路径 /config 下。

  • application.properties
  • application.yml

.yml 是 YAML (YAML Ain't Markup Language) 语言的文件,以数据为中心,比 json、xml 等更适合做配置文件。

配置文件的作用:修改 SpringBoot 自动配置时的默认值

1.1 基本语法

k:(空格)v 表示一对键值对(空格必须有!),以空格的缩进来控制层级关系。只要是左对齐的一列数据,都是同一个层级的。

server:
  port: 8081
  path: /hello

1.2 值的写法

1. 字面量(数字、字符串、布尔)

  • k: v 字面直接来写;字符串默认不用加上单引号或者双引号。
  • "" 不会转义字符串里面的特殊字符,特殊字符会作为本身想表示的意思。如:name: "zhangsan \n lisi"zhangsan 换行 lisi
  • '' 会转义特殊字符,特殊字符最终只是一个普通的字符串数据。如:name: 'zhangsan \n lisi'zhangsan \n lisi

2. 对象、Map

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

friend:
  lastName: Green
  age: 13

行内写法:

friend: {lastName: Green, age: 13}

3. 数组、List、Set

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

pets:
  - cat
  - dog
  - pig

行内写法:

pets: [cat, dog, pig]

1.3 示例

1.3.1 @ConfigurationProperties

@Component // 只有这个类是容器中的组件,才能使用容器提供的 @ConfigurationProperties 功能
@ConfigurationProperties(prefix = "person")
public class Person {
public class Person {
    private String userName;
    private Boolean boss;
    private Date birth;
    private Integer age;
    private Pet pet;
    private String[] interests;
    private List<String> animal;
    private Map<String, Object> score;
    private Set<Double> salarys;
    private Map<String, List<Pet>> allPets;
}
// ················································
@Data
public class Pet {
    private String name;
    private Double weight;
}

1.3.2 配置文件处理器

<dependencies>
    ...

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

    ...
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <!-- 打包的时候把它排除掉 -->
            <configuration>
                <excludes>
                    <exclude>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-configuration-processor</artifactId>
                    </exclude>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>

1.3.3 application.yml

先生成创建 yml 文件的快捷方式:

person:
  userName: zhangsan
  boss: false
  birth: 2021/08/19 11:12:13
  age: 23
  pet:
    name: tomcat
    weight: 23.4
  interests: [马拉松, 游泳]
  animal:
    - jerry
    - mario
  score:
    english:
      first: 30
      second: 40
      third: 50
    math: [131, 140, 148]
    chinese: {first: 128, second: 136}
  salarys: [3999, 4999.98, 5999.99]
  allPets:
    sick:
      - {name: tom}
      - name: jerry
        weight: 47
    health: [{name: mario, weight: 47}]

1.3.4 使用测试

/*
 * SpringBoot 单元测试:可以在测试期间很方便的将组件注入进容器
 */
@RunWith(SpringRunner.class)
@SpringBootTest
class Springboot01HelloworldQuickApplicationTests {

    @Autowired
    Person person;

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

}

1.3.5 使用 prop 文件测试

# IDEA 使用的是 UTF-8
person.last-name=刘
person.age=13
person.birth=2020/01/01
person.boss=false
person.map.k1=v1
person.map.k2=v2
person.list=a, b, c
person.pet.name=xiaohei
person.pet.age=1

结果出现乱码,解决办法如下:

1.4 @Value

@Component
public class Person {
    @Value("${person.last-name}")
    private String lastName;
    @Value("#{11*2}")
    private Integer age;
    @Value("true")
    private Boolean boss;
}

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

3. 配置文件占位符

  1. 配置文件中可以使用随机数
    ${random.value}、${random.int}、${random.long}
    ${random.int(10)}、${random.int[1024,65536]}
    
  2. 属性配置占位符:可以在配置文件中引用前面配置过的属性,${app.name:默认值} 来指定找不到属性时的默认值。

4. 导入配置注解

4.1 @PropertySource

加载指定的配置文件

@PropertySource(value={"classpath:person.properties"})
@Component
@ConfigurationProperties(prefix = "person")
public class Person {...}

4.2 @ImportResource

导入 Spring 的配置文件,让配置文件里面的内容生效。因为 SpringBoot 里面没有 Spring 的配置文件,我们自己编写的配置文件,也不会自动识别;想让 Spring 的配置文件生效,加载进来,就必须把 @ImportResource 标注在一个配置类(比如主启动类) 上。

@ImportResource(locations = {"classpath:beans.xml"})
@SpringBootApplication
public class Springboot01HelloworldQuickApplication { main()... }

4.3 @Configuration

Spring Boot 推荐给容器中添加组件的方式:使用全注解的方式。类上标注解 @Configuration 表明当前类是个配置类,用来替代之前的 Spring 配置文件;再使用 @Bean 给容器中添加组件。

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

5. Profile

https://docs.spring.io/spring-boot/docs/2.4.3/reference/html/spring-boot-features.html#boot-features-profiles

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

5.1 多 Profile 文件

多环境配置时,文件名可以是 application-{profile}.properties/yml

但默认配置文件 application.yml 任何时候都会加载:

server:
  port: 9999
spring:
  profiles:
    active: dev     # 默认配置与环境配置同时生效,同名配置项则 profile 配置优先

profile 支持分组,不仅能指定一个配置文件,还可以多个:

spring.profiles.active=prods
spring.profiles.group.prods[0]=prod1    # application-prod1.yml
spring.profiles.group.prods[1]=prod2    # application-prod2.yml

5.2 @Profile 注解

/**
 * @author 6x7
 * @Description 测试 @Profile 条件装配功能。若标注在类上,就是在指定环境时才会加载类。
 */
@Configuration
public class MyProfileConfig {

    @Bean
    @Profile("test")
    public Color red() {
        return new Color("red");
    }

    @Bean
    @Profile("prod")
    public Color green() {
        return new Color("green");
    }

    @Bean
    @Profile("dev")
    public Color blue() {
        return new Color("blue");
    }
}

5.3 激活指定 Profile

书写位置 命令
命令行(优先) --spring.profiles.active=dev
配置文件 spring.profiles.active=dev
JVM 参数 spring.profiles.active=dev

6. 外部化配置

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

You can use a variety of external configuration sources, include Java properties files, YAML files, environment variables, and command-line arguments.

【补充】打包配置

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.*</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.*</include>
            </includes>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

6.1 加载顺序

SpringBoot 也可以从以下位置加载配置(Low → High);其中高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置。

6.2 加载位置

Spring Boot 启动会扫描以下位置的 application.properties/yml 文件作为 Spring Boot 的默认配置文件。

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

  1. classpath 根路径
  2. classpath 根路径下 config 目录
  3. jar 包当前目录
  4. jar 包当前目录的 config 目录
  5. [Linux] /config 目录

项目打包好以后,运维可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置以更改默认顺序。指定配置文件和默认加载的这些配置文件共同起作用形成互补配置:

java -jar spring-boot-02-config.jar --spring.config.location=U:/application.properties

总结下来就是“越靠近外面优先级越高”。

posted @ 2021-09-14 21:36  tree6x7  阅读(92)  评论(0编辑  收藏  举报