11

我正在尝试根据某个 Maven 配置文件是否处于活动状态来配置带有数据库信息的 Spring 配置文件。我已经看到了一些答案,但我无法将它们放在一起。

我有一个这样的 Maven 配置文件:

<profiles>
    <profile>
        <id>production</id>
        <activation>
            <property>
                <name>environment.type</name>
                <value>prod</value>
            </property>
        </activation>
    </profile>

    <profile>
        <id>development</id>
        <activation>
            <property>
                <name>environment.type</name>
                <value>dev</value>
            </property>
        </activation>

        <!-- Database properties for Spring -->
        <properties>
            <db.driver>oracle.jdbc.driver.OracleDriver</db.driver>
            <db.type>oracle</db.type>
            <db.host>192.168.0.0</db.host>
            <db.port>1521</db.port>
            <db.name>myDb</db.name>
            <db.url>jdbc:${db.type}:thin:@${db.host}:${db.port}:${db.name}</db.url>
        </properties>

还有一个像这样的 settings.xml 文件:

<servers>
  <server>
    <id>development</id>
    <username>jsmith</username>
    <password>secret</password>
  </server>
</servers>

....

<profiles>
  <profile>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>

    <properties>
      <environment.type>dev</environment.type>
    </properties>
  </profile>
</profiles>

在 servlet-context.xml 中:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
    <property name="driverClassName">
        <value>${db.driver}</value>
    </property>

    <property name="url">
        <value>${db.url}</value>
    </property>

    <property name="username">
        <value>${db.username}</value>
    </property>

    <property name="password">
        <value>${db.password}</value>
    </property>

    <property name="maxActive">
        <value>10</value>
    </property>

    <property name="maxIdle">
        <value>1</value>
    </property>
</bean>

我的问题基本上是,如何将 Maven 属性放入 servlet-context.xml 文件中?我需要一个 .properties 文件吗?我对 Maven 中的过滤和 Spring 中的 PropertyPlaceholderConfigurer 了解一些,但我不知道如何将它们组合在一起——或者它们是否组合在一起?或者有没有更简单的方法?

4

3 回答 3

10

我需要一个 .properties 文件吗?

一般来说,是的,你需要使用 .properties 文件,这是我们通常做的,特别是在 spring 上下文文件中处理数据库连接配置。

.properties 文件的目的是提供在应用程序运行时配置数据库连接的能力(对于 Web 应用程序,通常需要在 .properties 文件更改后重新启动应用程序容器/服务器)。这通常在不同环境(DEV/TEST/UAT/PROD)中的应用程序部署/安装步骤中完成。

将这些数据库连接设置存储在 pom.xml 中并不是一个好习惯,因为 pom.xml 的目的是用于项目描述并且仅在应用程序构建时使用一次(例如 mvn deploy)。而且在大多数情况下,即使它被打包到最终的 jar/war 文件中,我们也并不真正关心和在构建应用程序后触摸它。

要在 spring 上下文中使用 .properties 文件,请在 applicationContext 中定义一个 propertyConfigurer bean,例如:

<bean id="propertyConfigurer"
  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations">
    <list>
      <!-- Default location inside war file -->
      <value>classpath:db.properties</value>
      <!-- Environment specific location, a fixed path on server -->
      <value>file:///opt/my-web-app/conf/db.properties</value>
    </list>
  </property>
  <property name="ignoreResourceNotFound" value="true"/>
</bean>

希望这是有道理的。

于 2012-08-08T23:43:26.653 回答
5

使用我从两个答案和我的研究中学到的知识,我能够获得一个由 pom 控制的开发/生产系统,它可以设置正确的数据库值。

首先,在 pom 中,我创建了两个配置文件。

<!-- Production and Development Profiles -->

<profiles>
    <!-- Nike profile needs go here -->
    <profile>
        <id>production</id>
        <activation>
            <property>
                <name>environment.type</name>
                <value>prod</value>
            </property>
        </activation>
    </profile>

    <!-- Catalyst profile needs go here -->
    <profile>
        <id>development</id>
        <activation>
            <property>
                <name>environment.type</name>
                <value>dev</value>
            </property>
        </activation>

        <build>

            <!-- This holds the properties for the Spring context file.
                 Database values will be changes to development. -->
            <filters>
                <filter>src/main/resources/dev.database.properties</filter>
            </filters>

            <resources>

                <!-- This is the directory that holds the Spring context
                     file.  The entire folder is searched, so either no
                     other file should have place holders or you should
                     exclude other files from being filtered. -->
                <resource>
                    <directory>src/main/webapp/WEBINF/</directory>
                    <filtering>true</filtering>
                </resource>
            </resources>
    </profile>
</profiles>

在 servlet-context.xml 的 WEBINF 目录中,我放置了占位符:

<!-- For database, uses maven filtering to fill in placeholders -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${db.driver}" />
    <property name="url"             value="${db.url}" />
    <property name="username"        value="${db.username}" />
    <property name="password"        value="${db.password}" />
    <property name="maxActive">
        <value>10</value>
    </property>
    <property name="maxIdle">
        <value>1</value>
    </property>
</bean>

然后我创建了一个属性文件放在 src/main/resources

#
# Development database properties file
#
db.driver=oracle.jdbc.driver.OracleDriver
db.url=jdbc:oracle:thin:[USER/PASSWORD]@[HOST][:PORT]:SID
db.username=jsmith
db.password=s3cr3t

然后我可以启动 Maven

mvn -P developement clean install

或者有一个 settings.xml 为我设置正确的配置文件:

<settings>
  <profiles>
    <profile>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>

      <properties>
        <environment.type>dev</environment.type>
      </properties>
    </profile>
  </profiles>   
</settings>
于 2012-08-09T23:13:54.880 回答
2

主要问题是:您将如何将 WAR 文件部署到不同的环境?通过 RPM、jenkins 构建,手动?您是否还希望将相同的 WAR 文件部署到所有环境?

a)您希望通过 JENKINS 作业(或通过 maven 手动)部署您的 WAR,只需处理您的资源并在 jar 的构建过程中使用配置文件(mvn -P production clean deploy),maven pom 应包含代码像这样:

    <filters>
        <filter>${config.maven.plattform.resources}/environment/${config.environment.dir}/your_proyect.properties</filter>
    </filters>
    <resources>
        <resource>
            <directory>resources/servlet-context.xml</directory>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>target/generated-resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>

您应该在 your_proyect.properties 文件中定义您的属性(每个环境一个),并为所有不同的配置文件定义 config.environment.dir。

b) 您希望所有项目都使用相同的 WAR/RPM 等。然后,您必须在应用程序 servert 的 java 启动中将环境定义为属性: -DENVIRONMENT=production 然后使用参数化的 PropertyPlaceholderConfigurer 加载所有属性,正如 yorkw 指出的那样:

<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
        <value>classpath:environment/${ENVIRONMENT}/your_project.properties</value>
        </list>
    </property>
</bean>

还要记住将所有属性放在 WAR 中,WAR 构建的 pom 应该包含如下代码:

                <execution>
                    <id>copy-env-resources</id>
                    <!-- here the phase you need -->
                    <phase>validate</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${basedir}/src/main/webapp/WEB-INF/classes/environment/</outputDirectory>
                        <overwrite>true</overwrite>
                        <resources>
                            <resource>
                                <directory>${basedir}/${build_to_all_your_environments}</directory>
                                <includes>
                                    <include>**/*.properties</include>
                                </includes>
                            </resource>
                        </resources>
                    </configuration>
                </execution>

c)混合的:您可以手动选择一个环境而不是服务器中定义为属性的环境(-D),您可以通过使用默认属性来获取此环境,如果找不到,则使用该环境的环境,此步骤非常复杂,因为它需要另一组属性,如果您有兴趣查看我的帖子: deployment for different environment with maven and spring,我也对 c) 的更好解决方案感兴趣

于 2012-08-09T12:50:11.830 回答