0
点赞
收藏
分享

微信扫一扫

基于springboot实现自定义配置文件外部挂载

基于springboot实现自定义配置文件外部挂载

背景

spring支持载入jar包外的配置,但是仅仅只对application.properties主配置文件支持。这问题就大了,正式开发肯定不会把所有配置都写在主配置文件中。

理论

@PropertySource注解有一个factory参数,默认值是PropertySourceFactory.class,默认实现是DefaultPropertySourceFactory.class,这个参数就是用来指定配置文件加载工厂类的。
默认的实现是从jar包内查找配置文件,同时spring还有自带的外部文件资源类FileSystemResource,那要做的事情就很明显了。
spring默认的不是从jar包内查找吗,那我不变spring的原逻辑,我在它的基础上再加一层。不仅从jar内查找,额外从jar包外查找。规则如下:

jar包内有,jar包外没有,那自然是用jar包内的配置。
jar包内没有,jar包外有,自然是用jar包外的配置。
jar包内有,jar包外也有,使用jar包外的配置。
注意:这里是替换关系,不是补充关系。

编码

TomPropertySourceFactory 自定义配置文件载入工厂类

import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;

import java.io.IOException;

/**
 * @author TomShiDi
 * @description
 * @date 2022/3/14 21:30
 **/
public class TomPropertySourceFactory extends DefaultPropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) throws IOException {
        Resource fileSystemResource = null;
        // 判断jar包类有没有找到配置
        if (encodedResource.getResource() instanceof ClassPathResource) {
            String path = ((ClassPathResource) encodedResource.getResource()).getPath();
            fileSystemResource = new FileSystemResource(path);
        }
        // 如果外部配置也存在,则替换掉jar包内的配置
        if (fileSystemResource != null && fileSystemResource.exists()) {
            encodedResource = new EncodedResource(fileSystemResource, encodedResource.getEncoding());
        }
        // 调用原spring逻辑
        return super.createPropertySource(name, encodedResource);
    }
}

extra-config.properties 配置文件

extra.name=tomshidi
extra.properties.age=1000
extra.properties.sex='M'

ExtraConfig 配置类

import com.example.demo.factory.TomPropertySourceFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @author TomShiDi
 * @description
 * @date 2022/3/14 21:32
 **/
@Component
@PropertySource(value = "classpath:config/extra-config.properties",
        encoding = "UTF-8",
        factory = TomPropertySourceFactory.class)
@ConfigurationProperties(prefix = "extra")
public class ExtraConfig {
    private String name;

    private Map<String, Object> properties;

    public String getName() {
        return name;
    }

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

    public Map<String, Object> getProperties() {
        return properties;
    }

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

    @Override
    public String toString() {
        return "ExtraConfig{" +
                "name='" + name + '\'' +
                ", properties=" + properties +
                '}';
    }
}

运行效果

在这里插入图片描述

载入外部文件

目录结构如下

在这里插入图片描述
在这里插入图片描述

配置文件内容

extra.name='This is an extra properties'
extra.properties.age=1000
extra.properties.sex='M'

cmd启动jar的效果

在这里插入图片描述

在容器部署时以上操作挺好用的

举报

相关推荐

0 条评论