springboot学习(四十七) springboot中使@ProperySource适配yml文件

@PropertySource加载指定的属性文件(*.properties)到 Spring 的 Environment 中。可以配合 @Value 和@ConfigurationProperties 使用:@PropertySource 和 @Value组合使用,可以将自定义属性文件中的属性变量值注入到当前类的使用@Value注解的成员变量中;@PropertySource 和@ConfigurationProperties
组合使用,可以将属性文件与一个Java类绑定,将属性文件中的变量值注入到该Java类的成员变量中。

spring的@PropertySource注解只支持引入properties文件,引入yaml文件会报错,自定义PropertySourceFactory可以使之对yaml文件做支持

跟踪源码发现:
DefaultPropertySourceFactory#createPropertySource中实现读取配置文件逻辑,如下:

public class DefaultPropertySourceFactory implements PropertySourceFactory {

	@Override
	public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
		return (name != null ? new ResourcePropertySource(name, resource) : new ResourcePropertySource(resource));
	}

}

ResourcePrepertySource构造器:

public ResourcePropertySource(String name, EncodedResource resource) throws IOException {
		super(name, PropertiesLoaderUtils.loadProperties(resource));
		this.resourceName = getNameForResource(resource.getResource());
	}

PropertiesLoaderUtils#loadProperties(resource):

public static Properties loadProperties(EncodedResource resource) throws IOException {
		Properties props = new Properties();
		fillProperties(props, resource);
		return props;
	}

能够确定使用Properties 读取的配置文件,所以只能支持.properties类型的文件

为了对yaml文件做支持,继承DefaultPropertySourceFactory 重新实现读取方法,判断为yaml类型文件自定义读取逻辑,非yaml文件继续走之前的逻辑,如下:

package com.iscas.springboot.samples.property.resource;

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.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;

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

/**
 * 兼容配置,使得@PropertyResource注解也能支持yaml
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/6/21 21:24
 * @since jdk1.8
 */
public class MixPropertySourceFactory extends DefaultPropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        String sourceName = resource.getResource().getFilename();
        if (sourceName != null && (sourceName.endsWith(".yml") || sourceName.endsWith(".yaml"))) {
            //将yaml文件转为properties
            return new PropertiesPropertySource(name, convert(resource));
        } else {
            return super.createPropertySource(name, resource);
        }
    }

    private Properties convert(EncodedResource encodedResource) {
        YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
        factory.setResources(encodedResource.getResource());
        factory.afterPropertiesSet();
        return factory.getObject();
    }
}

测试:
定义一个yaml配置文件test-property-source.yml:

person:
  zhangsan:
    age: 18

使用:

package com.iscas.springboot.samples.property.resource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 测试@PropertyResource
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/6/21 21:37
 * @since jdk1.8
 */
@RestController
@RequestMapping("/test/property/resource")
@PropertySource(name = "test-property-source.yml", value = "classpath:test-property-source.yml", factory = MixPropertySourceFactory.class)
public class TestPropertyResource  {

    @Value("${person.zhangsan.age}")
    private int age;

    @GetMapping
    public String testPropertyResource() {
        System.out.println("张三年龄:" + age);
        return "success";
    }
}

访问这个接口,可以正常读取到张三年龄

2021-06-21 22:07:07.801  INFO 20404 --- [nio-5678-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-06-21 22:07:07.801  INFO 20404 --- [nio-5678-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2021-06-21 22:07:07.802  INFO 20404 --- [nio-5678-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
张三年龄:18
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值