Управление проектом с помощью Maven и Spring: как установить конфигурационный файл Spring с использованием профилей Maven?

Я пытаюсь настроить конфигурационный файл Spring с информацией о базе данных на основе того, активен ли определенный профиль Maven. Я видел ответы на это, но у меня возникли проблемы со всем этим.

У меня есть профиль 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 и PropertyPlaceholderConfigurer в Spring, но я не знаю, как их собрать - или они идут вместе? Или есть более простой способ?

Ответ 1

Используя то, что я узнал из двух ответов и моих исследований, я смог получить систему разработки/производства, контролируемую 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>

Ответ 2

Нужен ли мне файл .properties?

Вообще говоря, ДА, вам нужно использовать файл .properties, это то, что мы делаем обычно, особенно для обработки конфигурации подключения к базе данных в spring файле контекста.

Цель файла .properties - предоставить возможность настройки соединений базы данных во время выполнения приложения (для веб-приложения обычно требуется перезапуск контейнера/сервера приложения после изменения файла .properties). Обычно это делается на этапе развертывания/установки приложений в разных средах (DEV/TEST/UAT/PROD).

Не рекомендуется сохранять эти параметры подключения к базе данных в pom.xml, поскольку цель pom.xml предназначена для описания проекта и используется только один раз во время создания приложения (например, mvn deploy). И в течение большей части времени, даже если он упакован в финальный файл jar/war, нам все равно, и прикосновение к нему после создания приложения.

Чтобы использовать файл .properties в контексте spring, определите свойствоconfigurer 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>

Надеюсь, что это имеет смысл.

Ответ 3

Основной вопрос: как вы собираетесь развернуть свой WAR файл в разные среды?, через RPM, сборку jenkins вручную?, также вы хотите, чтобы один и тот же файл WAR был развернут во всех средах

a) вы хотите, чтобы ваша WAR была развернута в задании JENKINS (или вручную через maven), просто обработайте свои ресурсы и используйте профиль в процессе сборки банки (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 и т.д. для всех ваших проектов. Затем вы должны определить environmentemt как свойство в java-запуске приложения servert: -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, pom для сборки WAR должен включать код следующим образом:

                <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), вы можете получить это, используя свойства по умолчанию, если не нашли, то прибегните к тому, что для этой среды, этот шаг довольно запутан, так как для этого требуется другой набор свойств, если вам интересно проверить мой пост: развертывание для разных сред с maven и spring, меня также интересует лучшее решение для c)