1

我正在使用系统属性来定义特定于环境的属性文件的位置。但是,我想将该值覆盖为与集成测试不同的值。

这是我的生产弹簧设置。我正在使用自定义 PropertyPlaceholderConfigurer 来解析一些加密的属性文件值,但这在这里并不重要:

<-- Spring configuration in file service-spring-beans.xml -->
<bean class="com.mycompany.MyPropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:properties/${MY_ENVIRONMENT}/${MY_ENVIRONMENT}.properties</value>
        </list>
    </property>
    <property name="ignoreResourceNotFound" value="false"/>
    <property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>

在运行时,我们将 MY_ENVIRONMENT 的值定义为 Java 系统属性。这一切都按预期工作。但是,对于集成测试,我想将 MY_ENVIRONMENT 定义为“inttest”,因此会加载集成测试特定的属性文件 properties/inttest/inttest.properties。

我尝试使用集成测试加载的 spring 上下文来设置 id 为 MY_ENVIRONMENT 的 String bean:

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


    <context:component-scan base-package="com.mycompany.myclasses"/>


    <bean class="java.lang.String" id="MY_ENVIRONMENT">
        <constructor-arg value="inttest"/>
    </bean>
    <!-- this imports the production spring context -->
    <import resource="classpath:service-spring-beans.xml"/>

</beans>

但是, MY_ENVIRONMENT 的值未解决,并且在运行集成测试时出现此错误。

引起:org.springframework.beans.factory.BeanInitializationException:无法加载属性;嵌套异常是 java.io.FileNotFoundException:类路径资源 [properties/${MY_ENVIRONMENT}/${MY_ENVIRONMENT}.properties] 无法打开,因为它不存在

如何在不将系统属性传递给 JVM 的情况下在 inttest 时间覆盖 MY_ENVIRONMENT?

4

3 回答 3

3

由于我使用 maven surefire 插件来运行集成测试,因此最简单的解决方案是使用 surefire 插件配置设置系统属性,如下所示:

<configuration>
  <systemPropertyVariables>
      <MY_ENVIRONMENT>inttest</MY_ENVIRONMENT>
   </systemPropertyVariables>
   <!-- ... -->
<configuration>
于 2013-07-21T05:10:32.507 回答
2

由于您不想使用配置文件,因此您可以创建多个上下文并只包含所需的正确上下文文件。因此,对于集成测试,您拥有 application-context.xml 和 integration-property-context.xml 文件,而在 prod 环境中,您将包含 application-context.xml 和 production-property-context.xml 文件。我已经看到这种方法大量用于在 dev 和 prod 之间切换数据源,其中 dev 将是 BasicDataSource 实现,而 prod 环境引用 JDNI 数据源。

这种方法将帮助您避免 ActiveProfiles,但是您会遇到管理重复 bean 的问题,这可能是 ActiveProfiles 真正简化的问题。

于 2013-07-19T20:25:34.400 回答
1

您可以查看使用活动配置文件覆盖整个属性占位符实现。也就是说,默认(无配置文件)会启动您的属性占位符,但测试配置文件(例如'test')可以为属性占位符创建一个新的测试bean。

属性占位符的挑战之一是它在应用程序上下文启动的早期阶段加载,因此正常的覆盖 bean 可能无法工作。

于 2013-07-19T18:29:37.430 回答