程序员社区

@PropertySource 注解的使用


前言

       我们了解完 @ConfigurationProperties 注解的使用,知道了它可以将 application.yml 或 application.properties 主配置文件中的属性值与 Java Bean 对应属性进行注入

       此时就引出另一个问题,如果所有属性值都配置在 主配置文件 中,主配置文件就会越来越庞大,这显然是不可以的。此时我们可以使用 Spring 为我们提供的 @PropertySource 注解,去加载指定的配置文件,然后结合 @ConfigurationProperties 注解,便能够实现指定配置文件与 Java Bean 的注入操作

       接下来,我们就来用一个实例来了解一下。如何使用 @ PropertySource 注解来加载指定配置文件,实现配置文件与Java Bean 类的注入。


1.@PropertySource读取.properties配置文件

person.properties配置文件

      我们新建一个 person.properties 配置文件,用来存放 Person 类的配置信息。接下来使用 @ PropertySource 注解,来实现通过读取该配置,实现配置文件与 Java Bean 类的注入操作。

//person.properties
person.id=111
person.name=扛麻袋的少年
person.age=18
person.manager=true
person.birthday=2020/03/27
person.map.k1=v1
person.map.k2=v2
person.list=basketball,tennis,swim
person.address.province=山西省
person.address.distinct=晋中市
person.address.county=祁县

javaBean类

        添加 @PropertySource(value = {“classpath:person.properties”})注解,通过 value 属性让它去加载指定路径配置文件。代码如下:

@Component
@ConfigurationProperties(prefix = "person")
@PropertySource(value = "classpath:person.properties",encoding = "UTF-8")    //读取指定路径配置文件
public class Person {
   

    private String id;

    private String name;

    private int age;

    private boolean isManager;

    private Date birthday;

    private Map<String, Object> map;

    private List<String> list;

    private Address address;

    /** * 省略get/set/toString() 方法 */
 }
/** * Address类 */
public class Address {
   

    private String province;

    private String distinct;

    private String county;

    /** * 省略get/set/toString() 方法 */
}

测试:
  本次是在一个完整的项目中测试,所以我们将Person类使用@Autowired注入。如下图所示,它可以实现 person.properties 文件中的配置信息与自定义的 Person 类完成注入操作:
在这里插入图片描述

2.@PropertySource读取.yml配置文件

Spring Boot 默认不支持@PropertySource读取yaml 文件。

  Spring 4.3 通过引入 PropertySourceFactory 接口使之成为可能。PropertySourceFactory 是PropertySource 的工厂类。默认实现是 DefaultPropertySourceFactory,可以构造ResourcePropertySource 实例。

可以通过普通的是实现构造 createPropertySource, 需要做两点:
1.导入resource 到Properties 对象
2.构造 PropertySource 使用Properties

具体例子:

import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import org.springframework.lang.Nullable;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

/** * 自定义一个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;
        }
    }
}

注意:YAML 需要 SnakeYAML 1.18 或者更高版本。

@PropertySource 注解有一个 factory 属性,通过这个属性来注入 PropertySourceFactory,这里给出 YamlPropertySourceFactory的例子。

javaBean类

@Component
@ConfigurationProperties(prefix = "person")
@PropertySource(value = "classpath:person.yml",factory = YamlPropertySourceFactory.class,encoding = "UTF-8")  //读取指定路径配置文件
public class Person {
   

    private String id;

    private String name;

    private int age;

    private boolean isManager;

    private Date birthday;

    private Map<String, Object> map;

    private List<String> list;

    private Address address;

    /** * 省略get/set/toString() 方法 */
 }

person.yml配置文件

      我们新建一个 person.yml 配置文件,用来存放 Person 类的配置信息。(注意:冒号和value值之间要有一个空格哦)

person:
  id: 222
  name: 扛麻袋的少年
  manager: true
  birthday: 2020/03/27
  map:
    k1: v1
    k2: v2
  list: basketball,tennis,swim
  address:
    province: 山西省
    distinct: 晋中市
    county: 祁县

测试:

  本次同样是在一个完整的项目中测试,所以我们将Person类使用@Autowired注入。如下图所示,它可以实现 person.yml文件中的配置信息与自定义的 Person 类完成注入操作:
在这里插入图片描述

读取.yml配置,参考自:https://zhuanlan.zhihu.com/p/141814495

3.其他问题

  1.在使用@ConfigurationProperties注解时,遇到提示:Spring Boot Configuration Annotation Processor not configured
在这里插入图片描述
需要在maven中添加如下配置:

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

  2.如果读取到的配置内容,中文却是乱码的情况,需要Ctrl + Alt + S 进行设置,进入Editor---File Encoding 进行设置,将下图中的编码全改为UTF-8
在这里插入图片描述

也可以在@PropertySource注解中,使用encoding属性,指定编码格式为UTF-8
如下所示:
@PropertySource(value = “classpath:person.properties”,encoding = "UTF-8")
@PropertySource(value = “classpath:person.yml”,factory = YamlPropertySourceFactory.class,encoding = "UTF-8")

Tip:在改完编码后,可能之前配置文件中的中文会随着编码而变成乱码,删了中文重写一遍即可。


博主写作不易,加个关注呗

求关注、求点赞,加个关注不迷路 ヾ(◍°∇°◍)ノ゙

我不能保证所写的内容都正确,但是可以保证不复制、不粘贴。保证每一句话、每一行代码都是亲手敲过的,错误也请指出,望轻喷 Thanks♪(・ω・)ノ

赞(0) 打赏
未经允许不得转载:IDEA激活码 » @PropertySource 注解的使用

一个分享Java & Python知识的社区