2

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

我现在这样做的方式是配置数据源,并通过 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 或类似的东西上指定配置文件。

4

3 回答 3

3

我曾经解决过这个问题(在 Spring 支持配置文件之前很长一段时间):用于测试和生产的 spring 属性替换

现在 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>

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

对于第一种方法,我找到了这个解决方案,但我没有测试过:

<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>
于 2014-07-20T10:50:23.180 回答
0

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

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

试想一下,必须再次捆绑 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 之一,这在我目前正在运行的项目中工作得非常好,而且我们仍在发现更多要推送到数据库中的属性。

于 2014-07-20T19:59:38.543 回答
0

请阅读:

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".
于 2017-10-03T09:07:42.073 回答