2

我正在尝试使用 Spring 的新Environment支持移植我们的自定义属性占位符,但我不知道如何获得我们当前的占位符魔法。

我想要的是从类路径中读取一组默认的属性文件,然后让这些属性被其他地方的一堆属性文件覆盖(覆盖)。我不希望所有属性都只替换在另一组文件中设置的属性。

在 Spring 3.1 之前

<bean class="com.snaphop.spring.ConfigResourcesFactoryBean" id="customConfig">
    <property name="parameterName" value="customConfig"/>
    <property name="defaultResources" value="classpath*:META-INF/spring/*.properties"/>
</bean>

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" id="customPropertyPlaceholder">
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
    <property name="locations" ref="customConfig"/>
</bean>

现在 ConfigResourcesFactoryBean 只是一个神奇的 FactoryBean,它可以找到要提供给占位符配置的资源列表:

public class ConfigResourcesFactoryBean implements FactoryBean<Resource[]> {
// Loads a bunch of Resources (property files) 
// based on System.property/Environment variable "customConfig"
}

现在 customConfig 可能设置为-DcustomConfig=file://blah/*.propertiesexport customConfig=file://blah/*.properties

目录中的属性blah仅覆盖classpath*:META-INF/spring/*.properties. 因此,Resource[]从工厂返回的将是一个 union ,分别classpath*:META-INF/spring*.properties跟随file://blah/*.properties

现在它出现了,而不是我的Resource[]工厂,我可以进行自定义PropertySources并将其连接到 PlaceholderConfig 中,但这似乎与上述相比没有任何价值。

我不能使用ApplicationContextInitializer,因为我发誓它只适用于 Servlet 环境,因此不适用于集成测试(我不想在我的每一个单元测试上添加一个注释来告诉它什么时候我可以只是像以前一样设置系统属性)。

如何使用自定义源覆盖来自硬编码源的属性,而不必覆盖/实现一堆类?

4

1 回答 1

0

加班慢慢把原来的配置解析代码移植到新的 Spring Environment 处事方式上。

我在这个 StackOverflow 问题上谈到它:如何使用 IntelliJ 在特定于环境的运行时配置之间轻松切换?

您可以将代码视为 Gist,并使用我在大多数 Spring 项目中使用的相同配置逻辑。

遗憾的是,对于单元测试,Context Initializer 仅适用于 Spring 3.2。请参阅更新的@ContextConfiguration注释。对于使用 Spring 3.1 及更早版本的项目,我不得不使用旧的自定义属性占位符。

于 2014-06-02T14:40:54.663 回答