【问题标题】:Load different properties for development and deployment为开发和部署加载不同的属性
【发布时间】:2014-09-10 23:42:39
【问题描述】:

我有一个非常常见的用例——当我的程序处于开发模式、测试模式或部署模式时连接到不同的数据库。

我现在这样做的方式是配置一个数据源,并通过 bean:property 标签传递 ${...} 属性。

但是要获得 ${...},我正在做

<context:property-placeholder properties-ref="myProperties" />

在 xml 配置的底部,我有

<beans profile=test>
   <util:properties id=myProperties>
   </util>
</beans>
<beans profile=dev,default>
   <util:properties id=myProperties>
</beans>
<beans profile=prod>
  <util:properties id="myProperties>
</beans>

这似乎效率低下、过于冗长且容易出错。所有弹簧属性教程都告诉我 context:property-placeholder 是环境感知的,而 Environment 负责配置文件,那么我该如何简化呢?对我来说很直观,有一种更简单的方法,我就是想不通。

真的,我正在寻找的是在 context:properties-placeholder 或类似的东西上指定配置文件。

【问题讨论】:

    标签: spring properties-file spring-environment


    【解决方案1】:

    我曾经解决过这个问题(在 Spring 支持配置文件之前很长一段时间):spring property substitution for test and production

    现在 a 仍然会使用属性文件,但是我会通过配置文件选择它们。有很多方法可以做到这一点:

    最简单的是:

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

    另一个是:

    <beans profile="normal">
        <context:property-placeholder 
                 location="classpath*:META-INF/spring/config-normal.properties"/>
    </beans>
    <beans profile="test">    
          <context:property-placeholder
                 location="classpath*:META-INF/spring/config-test.properties"/>
    </beans>
    

    第一种方法的缺点是,当激活多个配置文件时,只会加载第一个配置文件的属性。当拥有多个配置文件时,我不确定第二种方法会发生什么。

    对于我找到this solution的第一种方法,但我没有测试过:

    <bean id="propertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
          <property name="locations">
            <list>
                <value>classpath*:META-INF/spring/*_${spring.profiles.active}.properties</value>
            </list>
          </property>
    </bean>
    

    【讨论】:

    • 个人资料绝对是这里的必经之路。用 JavaConfig 做同样的事情也很容易。
    【解决方案2】:

    虽然配置文件肯定是解决该问题的方法,但我认为这种方法为您仅在目标平台上发现的问题打开了另一扇大门。

    在我的项目中,我总是将属性外部化,并将尽可能多的属性转换为运行时参数。

    想象一下,必须再次捆绑 Jenkins/Sonar/etc,因为您的平台不会成为属性驻留在类路径中的配置文件的一部分。我不认为这些会是成功的项目;)

    至于 spring,您可以在 propertyconfigurer 中使用 'file://' 协议,允许替换来自类路径的“dedault”属性。因此,您有两个带有订单参数和其他属性的配置器标签。这是一个例子:

        <jee:jndi-lookup id="configDirectory" jndi-name="configDirectory"
        resource-ref="true" default-value="." />
    <jee:jndi-lookup id="datasource" jndi-name="jdbc/datasource"
        expected-type="javax.sql.DataSource" default-ref="localDatasource" />
    
    <!-- Allows fetching properties from multiple locations: -->
    <!-- external definition -> file://${configDirectory}/root-context.properties 
        -> declared in context.xml -->
    <!-- standard web application bundle -> /WEB-INF/spring/root-context.properties -->
    <!-- testing -> classpath:root-context.properties -->
    <context:property-placeholder location="${configDirectory:.}/context.properties"
        order="9" ignore-resource-not-found="true" ignore-unresolvable="true" />
    <context:property-placeholder
        location="/WEB-INF/spring/context.properties,
        classpath:context.properties"
        order="10" ignore-resource-not-found="true" ignore-unresolvable="true" />
    <context:property-placeholder location="classpath:spring/default.properties"
        order="100" />
    

    像这样,我们能够在本地构建它,在 maven 构建期间运行我们的单元和集成测试,在 UAT 上运行构建,如果一切正常,将构建从 UAT 复制到 PROD,而无需修改 war 文件。

    在属性中我们定义了所有在运行时不能改变的参数,本质上就是Hibernate参数加上一些其他的。

    其余的都作为简单的系统参数(键值对)存储在数据库中。有很多属性不需要修复。这包括:LDAP、MailSender、像 tempdir 等文件夹定义。

    由于数据源是最先启动的 bean 之一,这在我目前正在运行的项目中工作得非常好,我们仍在发现更多要推送到数据库的属性。

    【讨论】:

    • 配置文件可以在不改变战争的情况下切换
    • @doom777。是的,但是为什么要限制自己使用预定义的值呢?我在这里只说属性,而不是豆类。想想您有一个定义了数据源的生产配置文件的情况。无论出于何种原因,数据库移动并且连接字符串更改。您将不得不更新您的个人资料并重新创建战争。
    【解决方案3】:

    请阅读:

    https://examples.javacodegeeks.com/enterprise-java/spring/load-environment-configurations-and-properties-with-spring-example/

    <context:property-placeholder  location="
           classpath:application.properties,
            classpath:application${spring.profiles.active}.properties"
                                          ignore-unresolvable="true"/>
    
    mvn clean install -Dspring.profiles.active="profile_name".
    

    【讨论】:

      猜你喜欢
      • 2011-10-14
      • 1970-01-01
      • 2011-03-09
      • 2019-12-15
      • 2010-11-15
      • 2022-10-17
      • 2015-09-01
      • 2018-09-16
      • 1970-01-01
      相关资源
      最近更新 更多