正确使用Spring环境配置文件以管理PropertySourcesPlaceholderConfigurer和属性文件集

bal*_*teo 14 spring environment-variables properties-file spring-profiles

我正在处理Spring应用程序,我意识到我的管理属性的方式存在问题.我使用Spring环境配置文件来加载我的属性,我最近添加了更多配置文件,这使我的属性文件无法管理.

属性文件位于不同的文件夹中src/main/resources/META-INF/props/,eah文件夹与不同的Spring环境配置文件匹配.

我现在至少有5个配置文件,这意味着我有5个子文件夹,每个子文件夹包含具有相同名称但仅对某些键具有不同值的属性文件.

以下是它的外观:

属性文件屏幕截图

以下是我配置PropertyPlaceholders的方法:

@Configuration
public class PropertyPlaceholderConfiguration {

    @Profile(Profiles.CLOUD)
    static class cloudConfiguration {
        @Bean
        public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() throws IOException {
            PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
            propertySourcesPlaceholderConfigurer.setIgnoreUnresolvablePlaceholders(Boolean.TRUE);
            propertySourcesPlaceholderConfigurer.setLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:META-INF/props/cloud/*.properties"));
            return propertySourcesPlaceholderConfigurer;
        }
    }

    @Profile(Profiles.DEFAULT)
    static class defaultConfiguration {
        @Bean
        public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() throws IOException {
            PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
            propertySourcesPlaceholderConfigurer.setIgnoreUnresolvablePlaceholders(Boolean.TRUE);
            propertySourcesPlaceholderConfigurer.setLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:META-INF/props/default/*.properties"));
            return propertySourcesPlaceholderConfigurer;
        }
    }

    @Profile(Profiles.TEST)
    static class testConfiguration {
        @Bean
        public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() throws IOException {
            PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
            propertySourcesPlaceholderConfigurer.setIgnoreUnresolvablePlaceholders(Boolean.TRUE);
            propertySourcesPlaceholderConfigurer.setLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:META-INF/props/test/*.properties"));
            return propertySourcesPlaceholderConfigurer;
        }
    }

    @Profile(Profiles.DEV)
    static class devConfiguration {
        @Bean
        public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() throws IOException {
            PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
            propertySourcesPlaceholderConfigurer.setIgnoreUnresolvablePlaceholders(Boolean.TRUE);
            propertySourcesPlaceholderConfigurer.setLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:META-INF/props/dev/*.properties"));
            return propertySourcesPlaceholderConfigurer;
        }
     ...
    }
Run Code Online (Sandbox Code Playgroud)

总结一下,我的问题如下:

  • 键/值对在5个不同的文件夹中重复,因为只有少数值不同.

因此,我正在寻找一种新策略来管理不同环境之间的差异.

有人可以帮忙吗?

Lan*_*ley 5

有很多方法可以做到这一点,但我认为你是在正确的道路上.覆盖属性文件是通过BeanFactoryPostProcessors完成的,在这种情况下有两个实现可以帮助您,因此您不必从头开始:

PropertySourcesPlaceholderConfigurer和PropertyOverrideConfigurer.

这是使用PropertySourcesPlaceholderConfigurer的示例:

<bean id="someProperties" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer" abstract="true" >
    <property name="locations">
        <list>
            <value>classpath:database.properties</value>
            <value>classpath:email.properties</value>
        </list>
    </property>
    <property name="ignoreUnresolvablePlaceholders" value="false"/>
</bean>

<bean id="devProperties" parent="someProperties"  >
    <property name="properties" >
        <props >
            <prop key="database.username">Database Username used for Development Environment </prop> 
        </props>
    </property>
    <property name="localOverride" value="true" />
</bean>

<bean id="testProperties" parent="someProperties"  >
    <property name="properties" >
        <props >
            <prop key="database.username">Database Username used for Testing Environment </prop> 
        </props>
    </property>
    <property name="localOverride" value="true" />
</bean>
Run Code Online (Sandbox Code Playgroud)

在该示例中,您将默认属性加载到将用作其他bean的模板的bean中,并且在特定bean中,例如TestEnvironmentProperties Bean或DevEnvironmentProperties Bean,您只覆盖要从默认属性文件覆盖的特定属性.该示例仅显示如何覆盖特定属性而无需创建另一个属性文件,从那里您可以决定如何选择使用工厂,简单外观类或配置文件系统创建的bean,您喜欢和匹配的任何内容建筑.

此外,如果您认为此选项过于冗长,则可以使用property-placeholder元素.

我推荐你这本书:

Spring Framework入门,第二版

它只有你在第5章中需要的例子.我没有写它或者任何东西,我刚刚买了它,经过这么多糟糕的春季书后我很喜欢它.


Ala*_*Hay 2

将通用属性拉入单独的文件中,并指定该文件加上配置文件特定属性作为每个配置文件的输入。尚未使用基于 Java 的 Spring 配置,但以下是我在 XML 中的做法。假设您可以在代码中执行相同的操作:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

    <beans profile="default">
        <bean id="applicationPropertiesPlaceholder"
            class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <list>
                    <value>classpath:profiles/common.profile.properties</value>
                    <value>classpath:profiles/local.profile.properties</value>
                </list>
            </property>
        </bean>
    </beans>

    <beans profile="local">
        <bean id="applicationPropertiesPlaceholder"
            class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <list>
                    <value>classpath:profiles/common.profile.properties</value>
                    <value>classpath:profiles/local.profile.properties</value>
                </list>
            </property>
        </bean>
    </beans>

    <beans profile="trial">
        <bean id="applicationPropertiesPlaceholder"
            class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <list>
                    <value>classpath:profiles/common.profile.properties</value>
                    <value>classpath:profiles/trial.profile.properties</value>
                </list>
            </property>
        </bean>
    </beans>

    <beans profile="live">
        <bean id="applicationPropertiesPlaceholder"
            class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <list>
                    <value>classpath:profiles/common.profile.properties</value>
                    <value>classpath:profiles/live.profile.properties</value>
                </list>
            </property>
        </bean>
    </beans>

</beans>
Run Code Online (Sandbox Code Playgroud)