SpringBoot加载自定义配置文件

前言

SpringBoot的配置文件是application.properties或者application.yml。我们还可以根据spring.profiles.active配置项添加application-dev.properties或者application-prod.properties。这样,SpringBoot启动的时候就会自动添加对应环境的配置文件。但是,我们还想自定义一些配置文件。比如ES相关的配置文,我们想放在es.properties配置文件里,这样就不会导致application.properties配置文件的配置项过多,而且也方便查找,尤其是项目配置项特别多的时候。

网上的一般做法是使用@PropertySource注解来加载自定义配置文件。@PropertySource可以放在启动类上,加载所有自己想加载的配置文件,也可以放在任意配置类上,结合@ConfigurationProperties注解使用。但是spring的官方文档并不推荐这么使用,所以,我们根据官方文档的方法来尝试一下。

一、配置文件

我们先把不同环境的配置文件放在不同的文件夹里。如下图所示,dev开发环境的配置文件全部在dev文件夹下,prod生产环境的配置文件全部放在prod文件夹下。

image-20200824092241092

此时,自定义的wayne-es.properties配置文件并未被idea识别为SpringBoot的配置文件,添加配置的时候并没有任何提示。所以要把wayne-es.properties添加到配置文件中。根据下图一步一步操作,就可以把自定义的配置文件添加到SpringBoot配置文件中。

image-20200824093053056

二、配置pom文件

经过上面的一些配置之后,不同环境的配置文件就会有很多,但是项目运行的时候只需要一种环境的配置文件。所以,就需要在编译的时候做一些操作,只保留想要的某个环境下的配置文件。这个时候就需要配置一下pom文件,添加一些配置或者插件来实现相关操作。

2.1 配置 profiles

首先要先定义一下有哪些运行环境,一般有dev,test,prod。这些名字啥的都可以自己随便定义。具体配置如下:

<profiles>
    <profile>
        <!-- 生产环境 -->
        <id>prod</id>
        <properties>
            <profileActive>prod</profileActive>
        </properties>
    </profile>
    <profile>
        <!-- 本地开发环境 -->
        <id>dev</id>
        <properties>
            <profileActive>dev</profileActive>
        </properties>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <!-- 测试环境 -->
        <id>test</id>
        <properties>
            <profileActive>test</profileActive>
        </properties>
    </profile>
</profiles>

注意properties下的profileActive是自定义的一个变量,随便什么名字都可以。activeByDefault的意思是spring.profiles.active = dev。这样一来,在application.properties配置文件里就可以直接引用profileActive来进行运行环境的配置了。

spring.profiles.active=@profileActive@

两个@的意思是引用pom文件下profileActive变量的意思。可以在启动的时候查看一下日志,就知道profileActive值是什么了。

另外idea自带的maven插件也可以设置profileActive的值。这个插件在idea的右侧菜单栏里。

image-20200824094350644

Profiles下默认只有dev,其下面的值是根据你配置的profiles下的profile的id自动生成的。

2.2 配置resources

接下来配置编译时的逻辑,排除不需要的配置文件,把需要的配置文件放到resources根目录下。profileActive是引用的上一步配置的变量,project.build.directory是项目编译后的根目录,即target目录。

<build>
    <resources>
        <resource>
            <!--配置文件路径-->
            <directory>src/main/resources</directory>
            <!--开启filtering功能  -->
            <filtering>true</filtering>
            <!-- 排除文件 -->
            <excludes>
                <exclude>dev</exclude>
                <exclude>dev/*</exclude>
                <exclude>test</exclude>
                <exclude>test/*</exclude>
                <exclude>prod</exclude>
                <exclude>prod/*</exclude>
            </excludes>
        </resource>
        <!--将对应环境的资源配置,构建到最顶层-->
        <resource>
            <directory>src/main/resources/${profileActive}</directory>
            <filtering>false</filtering>
            <targetPath>${project.build.directory}/classes</targetPath>
        </resource>
    </resources>
</build>

三、加载自定义配置文件

根据spring官方文档,需要实现EnvironmentPostProcessor来加载自定义配置文件。注意,该实现类不需要添加任何注解!!

public class CustomEnvironmentPostProcessor implements EnvironmentPostProcessor {
	
    //配置文件名称匹配
    private ResourcePatternResolver resourceLoader = new PathMatchingResourcePatternResolver();
    //配置文件加载处理器
    private List<PropertySourceLoader> propertySourceLoaders;

    public CustomEnvironmentPostProcessor() {
        super();
        this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class, getClass().getClassLoader());
    }

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {

        for (PropertySourceLoader loader : this.propertySourceLoaders) {
            for (String fileExtension : loader.getFileExtensions()) {
                //这里定义了一下配置文件的前缀【wayne-】,加载所有前缀为wayne-的配置文件。前缀可以自定义
                String location = ResourceUtils.CLASSPATH_URL_PREFIX + "wayne-*." + fileExtension;
                try {
                    Resource[] resources = this.resourceLoader.getResources(location);
                    for (Resource resource : resources) {
                        List<PropertySource<?>> propertySources = loader.load(resource.getFilename(), resource);
                        if (!CollectionUtils.isEmpty(propertySources)){
                            System.out.println("加载配置文件:" + propertySources);
                            propertySources.forEach(environment.getPropertySources()::addLast);
                        }
                    }
                } catch (IOException e) {
                    System.out.println("配置文件加载失败:" + e.getMessage());
                }
            }
        }

    }
}

然后在resources下新建META-INF文件夹,文件夹里新建spring.factories文件。在spring.factories里添加配置即可,前面是固定的,后面是你的实现类的全类名。

org.springframework.boot.env.EnvironmentPostProcessor=com.wayne.config.CustomEnvironmentPostProcessor

这样,就会在启动类运行之前,把自定义的配置文件加载进去了。

我们可以实验一下,在启动类中读取一下自定义配置文件的内容,wayne-es.properties添加spring.elasticsearch=master配置,然后在启动类中添加如下代码。

public static void main(String[] args) {
    ConfigurableApplicationContext context = SpringApplication.run(EsSyncToolApplication.class, args);
    String property = context.getEnvironment().getProperty("spring.elasticsearch");
    System.out.println(property);
}

image-20200824100645697

image-20200824100804816

如图所示,自定义配置文件加载成功,配置文件里的配置内容也读取成功。

写在最后的话

如果配置项不是很多的话,就不需要加载自定义配置文件了,卸载一个文件里就解决了,没必要搞这么麻烦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值