基于springcloud之PropertySourceLocator扩展配置文件

前言

springcloud提供了PropertySourceLocator接口支持扩展自定义配置加载到spring Environment中。

即我们可以扩展PropertySourceLocator让spring读取我们自定义的配置文件,然后使用@Value注解即可读取到配置文件中的属性了

代码实现

首先我们在resources下面创建我们自己的配置文件my.json,文件内容为

{
  "my":{
    "json":{
      "property": "my json properties"
    }
  }
}

我们希望加载my.json.property到spring的Environment中

扩展PropertySourceLocator

/**
 * @description
 * 基于springcloud提供的PropertySourceLocator扩展配置文件,读取classpath下的my.json文件配置加载到spring环境变量中
 * 1、pom.xml依赖spring-cloud-starter包
 * 2、编写JsonPropertySourceLocator文件
 * 3、编写locate方法
 * 4、基于SPI方式在classpath下META-INF/spring.factories文件定义
 * org.springframework.cloud.bootstrap.BootstrapConfiguration=自定义JsonPropertySourceLocator
 *
 */
public class JsonPropertySourceLocator implements PropertySourceLocator {

    private final static String DEFAULT_LOCATION = "classpath:my.json";

    @Override
    public PropertySource<?> locate(Environment environment) {
        // TODO 微服务配置中心实现形式即可在这里远程RPC加载配置到spring环境变量中
        // 读取classpath下的my.json解析
        ResourceLoader resourceLoader = new DefaultResourceLoader(getClass().getClassLoader());
        Resource resource = resourceLoader.getResource(DEFAULT_LOCATION);
        if (resource == null) {
            return null;
        }

        return new MapPropertySource("myJson", mapPropertySource(resource));
    }

    /**
     * Resource转Map
     *
     * @param resource
     * @return
     */
    private Map<String, Object> mapPropertySource(Resource resource) {

        Map<String, Object> result = new HashMap<>();
        // 获取json格式的Map
        Map<String, Object> fileMap = JSONObject.parseObject(readFile(resource), Map.class);
        // 组装嵌套json
        processorMap("", result, fileMap);
        return result;
    }

    private void processorMap(String prefix, Map<String, Object> result, Map<String, Object> fileMap) {
        if (prefix.length() > 0) {
            prefix += ".";
        }
        for (Map.Entry<String, Object> entrySet : fileMap.entrySet()) {
            if (entrySet.getValue() instanceof Map) {
                processorMap(prefix + entrySet.getKey(), result, (Map<String, Object>) entrySet.getValue());
            } else {
                result.put(prefix + entrySet.getKey(), entrySet.getValue());
            }
        }
    }

    /**
     * JSON格式
     *
     * @param resource
     * @return
     */
    private String readFile(Resource resource) {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(resource.getFile());
            String str = "";
            byte[] readByte = new byte[1024];
            int length;
            while ((length = fileInputStream.read(readByte)) > 0) {
                str += new String(readByte, 0, length, "UTF-8");
            }

            return str;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

spring读取所有PropertySourceLocator的方式是基于SPI机制的,所以我们需要在classpath:META-INF/spring.factories定义org.springframework.cloud.bootstrap.BootstrapConfiguration,spring才能读取到我们自定义的配置JsonPropertySourceLocator

所以我们在resources下创建META-INF/spring.factories,定义以下内容org.springframework.cloud.bootstrap.BootstrapConfiguration=com.example.demo.cloud.sourceloader.JsonPropertySourceLocator

启动springboot,即可使用@Value读取我们的配置了。

扩展

使用这种方式非常灵活,只要在locate方法最后返回一个MapPropertySource对象即可,至于我们如何获取属性,这些我们都可以自己控制,例如我们实现从数据库读取配置来组装MapPropertySource,或者可以实现远程配置中心功能

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值