2.1.5 全局配置文件

​ 全局配置文件能够对一些默认的配置值进行修改。Spring Boot使用一个application.properties或application.yml/application.yaml的文件作为全局配置文件,该文件放在 【src/main/resources】目录或者类路径的 【/config】,

一般为放在resources目录。

我们可以在 application.properties / application.yml文件中定义Spring Boot定义项目的相关属性,当然,这些属性可以是系统属性、环境变量、命令参数等信息,也可以是自定义配置文件名称和位置。

# 指定项目运行端口
server.port=8080
# 指定项目应用上下文路径
server.servlet.context-path=/learn
# 指定项目名
spring.application.name=learn
2.1.5.1 配置自动提示

​ 编写配置时,由于我们配置的Person对象属性是我们自定义的,Spring Boot 无法自动识别,所有不会有任何属性提示。在实际开发中,为了出现代码提示的效果方便配置,在使用@ConfigurationProperties注解进行配置文件属性注入时,可以在pom.xml文件中添加Spring Boot提供的配置处理依赖器。

<!-- 配置处理器依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

添加配置后,需要重新编译、运行项目即可生效。

2.1.5.2 演示准备

​ 首先准备两个实体类:Pet、Person,下面通过application.properties和application.yml配置文件中的自定义配置属性注入到Person实体类中

@Data
public class Pet {
    private String type;
    private String name;
}
@Data
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private int id; // id
    private String name; // 名称
    private List hobby; // 爱好
    private String[] family; // 家庭成员
    private Map map;
    private Pet pet; // 宠物
}

@ConfigurationProperties(prefix = "person")注解的作用是将配置文件中以person开头的属性值通过setXXX()方法注入到实体类中

@Component注解的作用是将当前注入属性值的Person类对象作为Bean组件放到Spring容器中,只有这样才能被@ConfigurationProperties赋值

2.1.5.3 application.properties
person.id=1
person.name=张三
person.hobby=吃饭,睡觉,打豆豆
person.family=father,mother
person.map.k1=v1
person.map.k3=v2
person.pet.type=cat
person.pet.name=麻花

测试类

// 测试启动类,并加载Spring Boot测试注解
@RunWith(SpringRunner.class)
// 标记为Spring Boot单元测试类,并加载项目的ApplicationContext上下文环境
// classes 知道项目主程序启动类
@SpringBootTest(classes = LearnApplication.class)
public class LearnApplicationTest {

    @Autowired
    private Person person;

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

}

打印结果

Person(id=1, name=张三, hobby=[吃饭, 睡觉, 打豆豆], family=[father, mother], map={k1=v1, k3=v2}, pet=Pet(type=cat, name=麻花))

可以看出,正确打印出了Person类对象,说明application.properties配置文件属性配置正确,并通过相关注解自动完成了属性注入。

2.1.5.4 application.yaml

​ yaml文件格式是Spring Boot支持的一种JSON超集文件格式,相比传统的properties配置文件,yaml文件以数据为核心,是一种更为直观且容易被电脑识别的数据序列化格式。application.yaml配置文件的工作原理和application.properties是一样的,只不过yaml格式配置文件看起来更加简洁一些。

  • yaml文件看扩展名可以为 .yaml或 .yml
  • application.yml文件使用 “key:(空格)value” 格式配置属性,使用缩进控制层级关系

针对不同的数据类型有不同的格式

  • value值为普通数据类型(数字,字符串、布尔等)

    server:
      port: 8081
    spring:
      application:
        name: demo
    
  • value值为数组和单列集合

    主要有两种书写方式:缩进式写法和行内写法

    • 缩进式写法

      person:
        hobby:
          - 吃饭
          - 睡觉
          - 打豆豆
      

      person:
        hobby:
          吃饭,
          睡觉,
          打豆豆
      
    • 行内写法

      person:
        hobby: [吃饭,睡觉,打豆豆]
      

      person:
        hobby: 吃饭,睡觉,打豆豆
      
  • value值为Map集合和对象

    主要有两种书写方式:缩进式写法和行内写法

    • 缩进式写法

      person:
        map:
          k1: v1
          k2: v2
      
    • 行内式写法

      person:
        map: {k1: v1-1,k2: v2-2}
      

测试

在resources下创建 application.yml

person:
  id: 1
  name: 罗杰
  hobby: [吃饭,睡觉,打豆豆]
  family: father,mother
  map: {k1: v1-1,k2: v2-2}
  pet:
    type: cat
    name: 麻花

测试类

// 测试启动类,并加载Spring Boot测试注解
@RunWith(SpringRunner.class)
// 标记为Spring Boot单元测试类,并加载项目的ApplicationContext上下文环境
// classes 知道项目主程序启动类
@SpringBootTest(classes = LearnApplication.class)
public class LearnApplicationTest {

    @Autowired
    private Person person;

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

}

打印结果

Person(id=1, name=张三, hobby=[吃饭, 睡觉, 打豆豆], family=[father, mother], map={k1=v1, k3=v2}, pet=Pet(type=cat, name=麻花))

可以看出,正确打印出了Person类对象,说明application.yml配置文件属性配置正确,并通过相关注解自动完成了属性注入。

2.1.5.5 配置文件属性值注入

使用Spring Boot进行全局配置文件设置时:

  • 如果配置的属性是Spring Boot已有属性,例如服务端口server.port,那么Spring Boot内部会自动扫描并读取这些配置文件中的属性值并默认覆盖。
  • 如果配置的属性是用户自定义属性,例如刚刚自定义的Person实体类属性,还必须在程序中注入这些配置属性方可生效。

Spring Boot支持多种注入配置文件属性的方式,@ConfigurationProperties和@Value方式

2.1.5.5.1 @ConfigurationProperties

Spring Boot 提供 @ConfigurationProperties 注解用来快速、方便的将配置文件中自定义的属性批量注入到某个Bean对象的多个属性中。

@Data
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private int id; // id
    private String name; // 名称
    private List hobby; // 爱好
    private String[] family; // 家庭成员
    private Map map;
    private Pet pet; // 宠物
}

上述代码使用 @Component 和 @ConfigurationProperties(prefix = "person")将配置文件中的每个属性映射到Person类组件中。

2.1.5.5.2 @Value

@Value是 Spring 框架提供的,用来读取配置文件中的属性值,并逐个注入到Bean对象的对应属性中,Spring Boot从Spring框架中对@Value注解进行了默认继承,所以在Spring Boot框架中还可以使用该注解读取和注入配置文件属性值。

@Data
@Component
public class People {
    @Value("${people.id}")
    private Integer id;
    @Value("${people.name}")
    private String name;
}
people:
  id: 1
  name: 李四

测试结果

People(id=1, name=李四)

可以看出,属性值正确打印,通过@Value可以进行配置文件属性值进行注入。

使用@Value注解使用注意事项

  • 如果使用@Value,在配置文件中配置对应属性或者设置默认值,否则会出现异常

    Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'people.name' in value "${people.name}"
    

    默认值设置方式示例

    @Data
    @Component
    public class People {
        @Value("${people.id:10}")
        private Integer id;
        @Value("${people.flag:true}")
        private Boolean flag;
        // 设置默认值为空字符串
        @Value("${people.name:}")
        private String name;
        // 设置默认值为null
        @Value("${people.remark:#{null}}")
        private String remark;
    }
    
  • @Value注解对Map集合、对象以及yml文件格式的行内式写法的配置文件的属性注入都不支持,如果赋值会出现错误

    Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'people.name' in value "${people.name}"
    

2.1.6 自定义配置

Spring Boot免除了项目中大部分的手动配置,对于一些特定情况,我们可以通过修改全局配置文件以适应具体生成环境,可以说,几乎所有的配置都可以写在application.properties配置文件中,Spring Boot会自动加载全局配置文件从而免除我们手动加载的烦恼。

但是,如果我们自定义配置文件,Spring Boot是无法识别这些配置文件的,此时需要我们手动加载。

2.1.6.1 @PropertySource

对应这种加载自定义配置文件的需求,可以使用@PropertySource注解结合@Component注解的方式来实现。

@PropertySource注解作用是用于指定自定义配置文件的具体位置和名称,同时,为了保证Spring Boot能够扫描该注解,还需要在其类上添加@Component,表明该类交于Spring容器进行维护。

当然对于自定义配置文件中的属性值注入到对应的类属性值中,可以使用@ConfigurationProperties或者@Value注解进行属性值注入

示例

  1. 创建test.properties

    test.id=1
    test.name=zhangsan
    
  2. 创建配置类

    @Data
    @Component
    // 引入自定义配置文件的名称和位置
    @PropertySource(value = "classpath:test.properties", encoding = "UTF-8")
    @ConfigurationProperties(prefix = "test")
    public class MyProperties {
        private int id;
        private String name;
    }
    
  3. 测试

    // 测试启动器,并加载Spring boot 测试注解
    @RunWith(SpringRunner.class)
    // 标记该类为Spring boot 单元测试类,并加载项目的ApplicationContext上下文环境
    @SpringBootTest
    class SpringbootDemoApplicationTests {
        @Autowired
        private MyProperties myProperties;
        @Test
        void contextLoads() {
            System.out.println(myProperties);
        }
    }
    

2.1.6.2 @Configuration

在Spring Boot框架中,推荐使用配置类的方式向容器中配置和组件

在Spring Boot框架中,通常使用 @Configuration 注解定义一个配置类,Spring Boot 会自动扫描和识别配置类,从而替换传统Spring框架中的XML配置文件。

当定义一个配置类后,还需要在类中的方法上使用@Bean注解进行组件配置,将方法的返回对象注入到Spring容器中,并且组件名称默认为方法名,当然也可以使用@Bean注解的name、value属性自定义组件的名称。

  1. 创建Config配置类

    // 标明该类为配置类
    @Configuration
    public class MyConfig {
        @Bean // 将返回值对象作为组件,添加到Spring容器中,标识id默认为方法名或者自定义@Bean(id)
        public MyService myService() {
            return new MyService();
        }
    }
    
  2. 测试

    // 测试启动器,并加载Spring boot 测试注解
    @RunWith(SpringRunner.class)
    // 标记该类为Spring boot 单元测试类,并加载项目的ApplicationContext上下文环境
    @SpringBootTest
    class SpringbootDemoApplicationTests {
        @Autowired
        private ApplicationContext applicationContext;
        @Test
        void contextLoads() {
            boolean myService = applicationContext.containsBean("myService");
            System.out.println(myService);
        }
    }
    

2.1.7 随机数设置

在Spring Boot配置文件中,随机值设置使用到了Spring Boot内嵌的RandomValuePropertySource类,对一些隐秘属性值或者测试用例属性值进行随机值注入

随机值设置的语法格式为 ${random.xx},xx标识需要指定生成的随机数类型和范围,可以是整数,uuid,或者字符串

@Data
@Component
@ConfigurationProperties(prefix = "myr")
public class MyRandom {

    private String secret; // 配置随机值
    private Integer number; // 配置随机整数
    private Long bignumber; // 配置随机Long类型整数
    private String uuid; // 配置随机uuid
    private int lessthanten; // 配置小于10的随机整数
    private int range; // 配置范围在[1024,5048]之间的随机整数

}
myr:
  secret: ${random.value}   # 配置随机值
  number: ${random.int}     # 配置随机整数
  bignumber: ${random.long} # 配置随机Long类型整数
  uuid: ${random.uuid}      # 配置随机uuid
  lessthanten: ${random.int(10)}  # 配置小于10的随机整数
  range: ${random.int[1024,5048]} # 配置范围在[1024,5048]之间的随机整数

2.1.8 参数间引用

在Spring Boot配置文件中,配置文件的 属性值还可以进行参数间的引用,也就是在后一个配置的属性值中引用先前已经定义多的属性,这样就可以直接解析其中的属性值了。

参数间引用的语法格式:${xxx},xxx表示先前在配置文件中已经配置过的属性名

好处:多处引用,一处配置

@Data
@Component
@ConfigurationProperties(prefix = "app")
public class App {
    private String name;
    private String describe;
}
app:
  name: 测试APP
  describe: ${app.name}是用来测试的