【问题标题】:spring property substitution for test and production用于测试和生产的弹簧属性替换
【发布时间】:2012-02-27 18:54:32
【问题描述】:

我在春天遇到了这个进行属性替换

<context:property-placeholder location="esb-project-config.properties"/>

但不幸的是,我们不希望在 xml 文件中出现这种情况,因为我们想在测试中重复使用该文件,但在 test.properties 文件中进行交换以进行测试。 IE。我们想测试所有的生产绑定,但要使用适合测试的属性,例如 localhost。我们如何加载 ApplicationContext 但使用不同的属性文件?

谢谢, 院长

【问题讨论】:

    标签: spring


    【解决方案1】:

    几种方法:


    1。 “订单”属性

    src/main/resources/your-conf.xml

    <context:property-placeholder 
             location="classpath:esb-project-config.properties"
             order="1"/>
    

    src/test/resources/your-test-config.xml

    <context:property-placeholder 
             location="classpath:esb-project-config.properties"
             order="0"/>
    

    如果您使用src/test/resources 作为测试类路径运行测试,以上将确保使用src/test/resources/esb-project-config.properties 覆盖src/main/resources/esb-project-config.properties

    这将覆盖整个property-placeholder,因此您必须提供应用程序中所需的所有属性以进行此测试property-placeholder。例如

    <context:property-placeholder 
             location="classpath:esb-project-config.properties,
                       classpath:some-other-props-if-needed.properties"
             order="0"/>
    

    2。 PropertyOverrideConfigurer

     <context:property-override 
              location="classpath:esb-project-config.test.properties"/>
    

    覆盖某些个人属性。一些例子here


    3。系统变量

    您可以使用前缀来控制特定于环境的属性,这可以通过使用系统变量来完成:

     <context:property-placeholder 
              location="${ENV_SYSTEM:dev}/esb-project-config.properties"/>
    

    在这种情况下,它将始终查看:

     <context:property-placeholder 
              location="dev/esb-project-config.properties"/>
    

    默认情况下,除非设置了 ENV_SYSTEM 系统变量。如果设置为qa,比如会自动往下看:

     <context:property-placeholder 
              location="qa/esb-project-config.properties"/>
    

    4。弹簧型材

    另一种方法是使 bean 配置文件特定。例如:

    <beans profile="dev">
      <context:property-placeholder 
               location="esb-project-config.dev.properties"/>
    </beans>
    
    <beans profile="qa">
      <context:property-placeholder 
               location="esb-project-config.qa.properties"/>
    </beans>
    

    将根据配置文件集加载适当的esb-project-config。例如这将加载esb-project-config.dev.properties:

    GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
    ctx.getEnvironment().setActiveProfiles( "dev" );
    ctx.load( "classpath:/org/boom/bang/config/xml/*-config.xml" );
    ctx.refresh();
    

    • 注意:“系统变量”和“系统配置文件”方法通常用于在不同的环境之间切换,而不仅仅是开发模式下的“开发 测试”,但仍然是有用的功能要注意。

    【讨论】:

    • 我尝试了 4) Spring profile 部分,但它似乎不起作用。我猜你不能在 中使用自定义命名空间?
    • 可以正常声明占位符,也可以使用:
    • 方法 4 对我有用。我没有在里面使用自定义命名空间。只需使用标准context:property-placeholder
    【解决方案2】:

    将property-placeholder配置放在一个额外的spring xml配置文件中。

    例如:

    • applicationContext.xml -- 用于没有任何属性占位符配置的正常配置
    • applicationContext-config.xml -- 仅包含加载生产配置文件的属性占位符。
    • testApplicationContext.xml。此文件 includes 与 applicationContext.xml 并用一个属性占位符和其他属性文件。

    在 Web 应用中,您可以使用此模式 applicationContext*.xml 加载所有生产 spring 上下文文件。

    对于测试,您只需要加载 testApplicationContext.xml 这将包括正常配置,但具有其他属性。

    【讨论】:

      【解决方案3】:
      • 在上下文标记上,您可以指出如果属性文件 不存在它不需要失败。
      • 属性文件按照声明的顺序加载。 (这 也可能是要在标签上声明的属性。不确定)
      • 如果一个属性被多次声明,最后加载的值是 用过。

      我们使用这三个功能如下:

      我们声明两个属性文件:

      classpath:esb-project-config.properties,
      classpath:esb-project-config-override.properties
      

      第一个属性文件包含合理的默认值和开发配置。此文件是您的应用程序的一部分。

      第二个属性文件是在测试类路径甚至应用服务器的生产类路径中可用的文件。此文件是应用程序的外部 这样我们就可以覆盖每个环境的属性,并且只有一个版本的应用程序。

      下面是我们使用的属性示例:

          <context:property-placeholder 
             ignore-resource-not-found="true" ignore-unresolvable="true" 
             location="classpath:esb-project-config.properties,classpath:esb-project-config-override.properties" />
      

      【讨论】:

        【解决方案4】:

        spring 3.1添加的我的首选方法如下:

        在您的 *-context.xml 中:

        <context:property-placeholder location="classpath:/web-${spring.profiles.active}.properties" />
        

        在 web.xml 中:

        <context-param>
            <param-name>spring.profiles.default</param-name>
            <param-value>prod</param-value>
        </context-param>
        

        然后可以在运行时指定环境,例如:

        mvn -Dspring.profiles.active=dev jetty:run
        

        或者你将参数传递给你的容器。

        【讨论】:

          【解决方案5】:

          看来:

            <beans profile="dev">
              <context:property-placeholder location="classpath:config/dev.properties"/>
            </beans>
            <beans profile="prod">
              <context:property-placeholder location="classpath:config/prod.properties"/>
            </beans>
          

          它不起作用。但你可以这样做:

          <context:property-placeholder location="classpath:config_${spring.profiles.active}.properties" />
          

          【讨论】:

          • 什么不适合你?我在我的应用程序中就是这样做的,没有任何问题。
          • @Ryan 我认为第一个对我不起作用,但我可能错了。如果我记得您不能将这样的属性占位符标记放在 beans 配置文件标记中。无论如何,使用 Spring 3.1 最好是在环境中注册 PropertySources,并且不要在上下文中声明任何本地属性文件 imho
          • 您使用什么技术来注册 PropertySources?初始化器? property-placeholder 标记应将属性放在 Environment 中。也就是说,您可能对“bean”标签内的属性占位符是正确的。我让它工作了,但是当我有两个不同的上下文,其中包含属性占位符的 bean 元素时,它似乎无法正常运行。可能与此错误有关。 jira.springsource.org/browse/SPR-9989
          • 我使用类似的东西:stackoverflow.com/questions/10669474/… 它允许对属性进行细粒度控制,您还可以在刷新上下文之前将属性添加到 Xml 应用程序上下文。
          猜你喜欢
          • 1970-01-01
          • 2011-10-23
          • 2017-12-14
          • 2016-07-08
          • 1970-01-01
          • 1970-01-01
          • 2019-02-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多