Spring Boot:(三)读取配置文件

  • 1. YAML语法
  • 2. 编写实例
  • 2.1 配置文件并添加依赖
  • application.yaml
  • application.properties
  • 添加依赖
  • 2.2 编写Spring代码
  • Persion类
  • 2.3 展示
  • 3. 属性注入的两种方式
  • 3.1 @ConfigurationProperties
  • 3.2 @Value
  • 4. 配置文件注入值数据校验@Validated
  • 5. 读取指定配置文件@PropertySource & ImportResource & 配置类@Configuration
  • 5.1 PropertySource:读取指定的配置文件
  • 5.2 @ImportResource:导入Spring的配置文件,让配置文件里面的内容生效(`不推荐`)
  • 5.3 配置类@Configuration、@Bean添加组件(`推荐`)
  • 6. 配置文件占位符
  • 6.1 随机数
  • 6.2 指定默认值
  • 6.3 实例


1. YAML语法

pass


2. 编写实例

2.1 配置文件并添加依赖
application.yaml
server:
  port: 8081

person:
  lastName: hello
  age: 18
  boss: false
  birth: 2017/12/12
  maps: {k1: v1, k2: v2}
  lists:
    - lisi
    - zhaoliu
  dog:
    name: 小狗
    age: 12

或者

application.properties
server.port=8081

# idea使用的是utf-8
# 设置编码格式,解决中文问题 lastName='å¼ ä¸‰'
# 配置person的值
person.last-name=张三
person.age=18
person.birth=2017/12/12
person.boss=false
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=dog
person.dog.age=15

修改编码格式

springboot启动读取外部配置文件 springboot读取配置文件源码_List

添加依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
2.2 编写Spring代码
Persion类
package com.study.springboot.bean;

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

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 将配置文件中配置的每一个属性的值,映射到这个组件中
 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;
 *      prefix = "person":配置文件中哪个下面的所有属性进行映射
 */
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;

    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Boolean getBoss() {
        return boss;
    }

    public void setBoss(Boolean boss) {
        this.boss = boss;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public Map<String, Object> getMaps() {
        return maps;
    }

    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }

    public List<Object> getLists() {
        return lists;
    }

    public void setLists(List<Object> lists) {
        this.lists = lists;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    @Override
    public String toString() {
        return "Person{" +
                "lastName='" + lastName + '\'' +
                ", age=" + age +
                ", boss=" + boss +
                ", birth=" + birth +
                ", maps=" + maps +
                ", lists=" + lists +
                ", dog=" + dog +
                '}';
    }
}

Dog类:

package com.study.springboot.bean;

import org.springframework.stereotype.Component;

@Component
public class Dog {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
2.3 展示

编写单元测试用例,并运行

package com.study.springboot;

import com.study.springboot.bean.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;


/**
 * Spring Boot 单元测试
 * 可以在测试期间很方便的类似编码一样进行自动注入
 */

@SpringBootTest
class HelloworldApplicationTests {

    @Autowired
    Person person;

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

}
.   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.4)

2021-09-06 16:36:34.969  INFO 37524 --- [           main] c.s.s.HelloworldApplicationTests         : Starting HelloworldApplicationTests using Java 1.8.0_192 on B000000383562P with PID 37524 (started by liyabin01 in /Users/liyabin01/Desktop/java代码仓库/java-notes/spring-boot-01-helloworld-quick)
2021-09-06 16:36:34.984  INFO 37524 --- [           main] c.s.s.HelloworldApplicationTests         : No active profile set, falling back to default profiles: default
2021-09-06 16:36:38.009  INFO 37524 --- [           main] c.s.s.HelloworldApplicationTests         : Started HelloworldApplicationTests in 3.572 seconds (JVM running for 5.554)

Person{lastName='hello', age=18, boss=false, birth=Tue Dec 12 00:00:00 CST 2017, maps={k1=v1, k2=v2}, lists=[lisi, zhaoliu], dog=Dog{name='小狗', age=12}}

3. 属性注入的两种方式

@ConfigurationProperties

@Value

功能

批量注入配置文件中的属性

一个一个指定

松散绑定(松散语法)

支持

不支持

SpEL

不支持

支持

JSR303数据校验

支持

不支持

复杂类型封装(例如Map)

支持

不支持

配置文件yaml还是properties都能获取值

  • 如果支持在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value
  • 如果专门编写一个JavaBean来和配置文件进行映射,直接使用@ConfigurationProperties
3.1 @ConfigurationProperties

特点:

  • 可以按对象进行配置application.properties
/**
 * 将配置文件中配置的每一个属性的值,映射到这个组件中
 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;
 *      prefix = "person":配置文件中哪个下面的所有属性进行映射
 */
@Component
@ConfigurationProperties(prefix = "person")
public class Person {

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

    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
}

输出:

Person{lastName='hello', age=18, boss=false, birth=Tue Dec 12 00:00:00 CST 2017, maps={k1=v1, k2=v2}, lists=[lisi, zhaoliu], dog=Dog{name='小狗', age=12}}
3.2 @Value

特点:

  • 每个属性都要单独写
  • 支持${}#{}两种方式
/**
 * 将配置文件中配置的每一个属性的值,映射到这个组件中
 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;
 *      prefix = "person":配置文件中哪个下面的所有属性进行映射
 */
@Component
//@ConfigurationProperties(prefix = "person")
public class Person {

    /**
     * <bean class="Person">
     *     <property name="lastName" value="字面量/${key}从环境变量、配置文件中获取值/#{SpEL}表达式"></property>
     * </bean>
     */
    @Value("${person.last-name}")
    private String lastName;
    @Value("#{11*2}")
    private Integer age;
    @Value("true")
    private Boolean boss;
    private Date birth;

    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
Person{lastName='å¼ ä¸‰', age=22, boss=true, birth=null, maps=null, lists=null, dog=null}

4. 配置文件注入值数据校验@Validated

使用注解@Validated


5. 读取指定配置文件@PropertySource & ImportResource & 配置类@Configuration

5.1 PropertySource:读取指定的配置文件

将person的配置抽取出单独的配置文件:person.properties

springboot启动读取外部配置文件 springboot读取配置文件源码_java_02

# idea使用的是utf-8
# 设置编码格式,解决中文问题 lastName='å¼ ä¸‰'
# 配置person的值
person.last-name=张三
person.age=18
person.birth=2017/12/12
person.boss=false
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=dog
person.dog.age=15

Person类:

增加注解@PropertySource(value = {"classpath:person.properties"})

package com.study.springboot.bean;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 将配置文件中配置的每一个属性的值,映射到这个组件中
 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;
 *      prefix = "person":配置文件中哪个下面的所有属性进行映射
 */
@PropertySource(value = {"classpath:person.properties"})
@Component
@ConfigurationProperties(prefix = "person")
public class Person {

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

    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
}
5.2 @ImportResource:导入Spring的配置文件,让配置文件里面的内容生效(不推荐

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

想让Spring的配置文件生效,加载进来;@ImportResource标注在一个配置类上

@ImportResource(locations = {"classpath:beans.xml"})
导入Spring的配置文件让其生效
5.3 配置类@Configuration、@Bean添加组件(推荐

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

  • 配置类 等价于 Spring配置文件
  • 使用@Bean给容器中添加组件
package com.study.springboot.config;

import com.study.springboot.service.HelloService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Configuration指明当前类是一个配置累;就是来替代之前的spring配置文件beans.xml
 */
@Configuration
public class MyAppConfig {

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

6. 配置文件占位符

RandomValuePropertySource:配置文件中可以使用随机数

6.1 随机数
  • ${random.value}
  • ${random.int}
  • ${random.long}
  • ${random.int(10)}
  • ${random.int[1024,65536]}
6.2 指定默认值
  • ${person.dog-age:15}
6.3 实例

修改配置文件:

# idea使用的是utf-8
# 设置编码格式,解决中文问题 lastName='å¼ ä¸‰'
# 配置person的值
person.last-name=zhangsan${random.uuid}
person.age=${random.int}
person.birth=2017/12/12
person.boss=false
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=${person.last-name}_dog
person.dog.age=${person.dog-age:15}		# 默认值

打印Person对象的属性:

Person{lastName='zhangsan30be419a-52ef-4c62-be7b-446f226b8181', age=-1424531156, boss=false, birth=Tue Dec 12 00:00:00 CST 2017, maps={k1=v1, k2=v2}, lists=[a, b, c], dog=Dog{name='zhangsan5ce8d5de-be44-4652-af72-1d42777181f0_dog', age=15}}