Springboot-配置文件

1. SpringBoot 配置文件格式

1. properties
2. yml

properties 优先级高于 yml。

自动识别的配置文件:bootstrap.yml 和 application.yml,bootstrap.yml 先于 application.yml 加载,一般用于系统级别的配置,application.yml 一般用于项目级别的配置

Springboot 官方的配置:https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#appendix.application-properties.web

2. @Value

读取单个配置文件

spring:
  application:
    name: yqa
@Value("${spring.application.name}")
private String appName;

引号的问题:

str1: hello\nworld
str2: 'hello\nworld'
str3: "hello\nworld"
@Value("${str1}")
public String str1;

@Value("${str2}")
public String str2;

@Value("${str3}")
public String str3;

@RequestMapping("/quote")
public void quote(){
    System.out.println(str1);
    System.out.println(str2);
    System.out.println(str3);
}

结论:默认不用引号,单引号中特殊字符还是字面的意思,双引号会进行转义

3. @ConfigurationProperties

1. 对象的配置和读取

1. 配置文件

# 第一种方式
dog1:
  name: yq
  age: 29

#第二种方式
dog2: { name : yl, age : 27}

第二种方式不常见,在读取时候,只要 @ConfigurationProperties(prefix = "dog2") 就可以了

2. 配置实体类

package com.demo.config;

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

@Data
@Component
@ConfigurationProperties(prefix = "dog1")
public class Dog {
    private String name;
    private int age;
}

3. 引用

@Autowired
private Dog dog;

@RequestMapping("obj/quote")
public void test1(){
    System.out.println(dog.getAge());
    System.out.println(dog.getName());
}

2. 集合的配置和读取

1. 配置文件

# 第一种方式
cat1:
  list:
    - yq
    - yl
    - pz

#第二种方式
cat2: { list: [ yl, yq, pz] }

2. 配置实体类

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

import java.util.List;

@Data
@Component
@ConfigurationProperties(prefix = "cat1")
//@ConfigurationProperties(prefix = "cat2")
public class Cat {
    private List<String> list;
}

3. 引用

@Autowired
private Cat cat;

@RequestMapping("/cat/quote")
public void test2(){
    System.out.println(cat.getList());
}

4. Environment

org.springframework.core.env.Environment 引用可以直接引用配置文件

1. 配置文件

spring:
  application:
    name: yqa

2. 读取配置

@Autowired
private Environment environment;

@RequestMapping("/env/quote")
public void test3(){
    System.out.println(environment.getProperty("spring.application.name"));
}

5. @PropertySource

上述 @ConfigurationProperties,@Value 默认都是读取主配置文件,也就是默认配置文件 application.yml、bootstrap.yml 等。通过 @PropertySource 可以引入指定的配置文件。

1. 读取 .properties 文件

1. 自定义配置文件

pro.test=我是测试

创建一个 my.properties 文件,放在 Springboot 默认的静态资源目录下,也就是 resource 目录下

2. @PropertySource 引入配置文件

@Data
@Component
@ConfigurationProperties(prefix = "chicken")
@PropertySource(value = "classpath:my.properties", encoding = "utf-8")
public class Chicken {
    private String name;
    private String age;
}

这个注解可以用在启动类上,也可以用在其他 Spring 可以扫描到的类上,然后就可以像默认的 application.properties 配置文件中的配置一样使用。

3. 使用示例

@Value("${pro.test}")
private String proTest;

@Autowired
private Chicken chicken;

@RequestMapping("/self/quote")
public void test4(){
    System.out.println(proTest);
    System.out.println(chicken.getName() + ";" + chicken.getAge());
}

2. 读取 .yml 文件

默认是不允许读取指定 yml 配置文件的,不过在 Spring 4.3 后通过引入 PropertySourceFactory 接口可以实现。

1. 创建 yml 配置文件工厂类

public class YamlPropertySourceFactory implements PropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
        Properties propertiesFromYaml = loadYamlIntoProperties(resource);
        String sourceName = name != null ? name : resource.getResource().getFilename();
        return new PropertiesPropertySource(sourceName, propertiesFromYaml);
    }

    private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException {
        try {
            YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
            factory.setResources(resource.getResource());
            factory.afterPropertiesSet();
            return factory.getObject();
        } catch (IllegalStateException e) {
            // for ignoreResourceNotFound
            Throwable cause = e.getCause();
            if (cause instanceof FileNotFoundException)
                throw (FileNotFoundException) e.getCause();
            throw e;
        }
    }
}

2. 创建 yml 配置文件

yq.yml:

person:
  name: yq
  age: 29
  home: minhang

3. 引入自定义的 yq.yml 配置文件

import com.demo.factory.YamlPropertySourceFactory;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "person")
@PropertySource(value = "classpath:yq.yml", encoding = "utf-8", factory = YamlPropertySourceFactory.class)
public class Person {
    private String name;
    private String age;
    private String home;
}

这里通过 PropertySource 注解的 factory 属性,使用自定义的 YamlPropertySourceFactory。

4. 引入使用

@Autowired
private Person person;

@RequestMapping("/self/yml")
public void test5(){
    System.out.println(person.getName() + ";" + person.getAge() + ";" + person.getHome());
}

6. 多环境配置文件

1. 配置文件选择环境

2. 启动命令行选择环境

java -jar .\springboot-yml-0.0.1-SNAPSHOT.jar --spring.profiles.active=test

3. 各种配置的优先级

以下是常用的 Spring Boot 配置形式及其加载顺序(优先级由高到低):

  1. 命令行参数

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

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

  4. 操作系统环境变量

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

  6. 配置文件(YAML文件、Properties 文件)

  7. @Configuration 注解类上的 @PropertySource 指定的配置文件

  8. 通过SpringApplication.setDefaultProperties 指定的默认属性

  以上所有形式的配置都会被加载,当存在相同配置内容时,高优先级的配置会覆盖低优先级的配置;存在不同的配置内容时,高优先级和低优先级的配置内容取并集,共同生效,形成互补配置。

4. 属性占位符

app.name=MyApp
app.description=${app.name} is a Spring Boot application written by ${username:Unknown}

7. Springboot 配置文件加载

1. 官网描述

官方介绍 24.3 章:https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/htmlsingle/

这里的 file:./ ,指的是项目根目录,如果是多模块项目,也是最外层目录,而不是模块目录。对于 jar 包来讲,file:./ 则是和 jar 包同目录级。而 classpath 则是资源目录,也就是 resource 目录下的文件,这里不仅有模块本身,还包括 jar 包的资源目录。

这里描述了 springboot 默认加载的配置文件,共有四个位置的配置文件被加载。所有配置文件全部加载,如果有共同的属性配置,高优先级覆盖低优先级。

优先级:file:./config/ > file:./ > classpath:/config/ > classpath:/

2. 对依赖的配置文件加载问题

上述加载的四个配置文件处,每处只能加载一个。

使用配置属性来查看配置文件加载情况:

logging:
  level:
    org:
      springframework:
        boot:
          context:
            config:
              ConfigFileApplicationListener: trace

对于以下依赖:

启动 ArticleMain 启动类,打印日志:

源码看 ConfigFileApplicationListener 中,看不懂也懒得看。

发现会加载依赖中的配置文件 application.properties,当本项目配置与依赖有相同的 application.yml 时,优先加载本项目的 application.yml。

也可以通过 environment 来查看具体加载了哪些属性:

3. 总结

  1. 默认加载的四个位置拥有相同的配置文件,比如 application.yml,可以同时存在,属性互补。相同属性优先级高的位置说了算。

  2. 四个位置中,每个位置可以加载四个文件,分别是 application.properties、application.xml、application.yml、application.yaml,前后按优先级。

  3. 会加载依赖包的 classpath 也就是 resource 下配置文件,前提是项目本身没有这个配置文件,有点话就有限加载自己的。

  4. 如果两个依赖都有这个配置,那么添加依赖的顺序,先添加的依赖优先。

  5. 优先级

    1. 位置优先级:file:./config/ > file:./ > classpath:/config/ > classpath:/

    2. 文件类型优先级:properties > xml > yml > yaml

    位置优先级 > 文件类型优先级

  6. 所有配置文件的配置项,最后都是加载到 Environment 中。

  7. application.yml 作用域在于当前应用有效,bootstrap.yml 系统级别的配置有效(一般采用远程配置的时候才会用到)。bootstrap 优先于 aplication.yml 加载。

posted @ 2023-08-24 10:45  primaryC  阅读(539)  评论(0编辑  收藏  举报