Java 如何使用 maven 配置文件设置 spring 活动配置文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25420745/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:21:30  来源:igfitidea点击:

How to set spring active profiles with maven profiles

javaspringmavenspring-profiles

提问by Gleeb

I have an application with maven as a build tool.

我有一个使用 maven 作为构建工具的应用程序。

I am using maven profiles to set up different properties from different profiles.

我正在使用 maven 配置文件从不同的配置文件设置不同的属性。

What i would like to do is that all active profiles in maven will be ported to spring active profiles as well so i can reference them in bean signature (@profile). but i am not sure how to do it.

我想要做的是 maven 中的所有活动配置文件也将被移植到 spring 活动配置文件,以便我可以在 bean 签名 ( @profile) 中引用它们。但我不知道该怎么做。

for example: consider the following maven setup

例如:考虑以下 maven 设置

<profiles>
    <profile>
        <id>profile1</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
        </properties>
    </profile>
    <profile>
        <id>profile2</id>
        <properties>
        </properties>
    </profile>
    <profile>
        <id>development</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
        </properties>
    </profile>
    <profile>
        <id>production</id>
        <properties>    
        </properties>
    </profile>
</profiles>

assuming i run maven with out specifying any other profiles i would like for spring to have profile1and developmentas active profiles.

假设我在没有指定任何其他配置文件的情况下运行 maven,我希望 spring 拥有profile1development作为活动配置文件。

采纳答案by poussma

You'll have to filter a resources of your application, for instance a property file, that holds the information of which profile to activate in spring.

您必须过滤应用程序的资源,例如一个属性文件,其中包含要在 spring 中激活哪个配置文件的信息。

For instance

例如

spring.profile = ${mySpringProfile}

And for each profile, define a value for this variable (mySpringProfile).

对于每个配置文件,为此变量定义一个值 ( mySpringProfile)。

During the build, this will be filtered accordingly to the value defined in the currently active profile.

在构建期间,这将根据当前活动配置文件中定义的值进行相应过滤。

Then during the bootstrap of your application you'll select the appropriated profile according to this file (can't help you more as you didn't gave us more information, but this is quite easy.

然后在应用程序的引导过程中,您将根据此文件选择合适的配置文件(无法帮助您更多,因为您没有向我们提供更多信息,但这很容易。

Note: I can't find a way to get the currently active profile in maven (something like project.profiles.active that holds your -P values), that's why you'll have to set a new variable for each profile.

注意:我找不到在 maven 中获取当前活动配置文件的方法(例如保存 -P 值的 project.profiles.active ),这就是您必须为每个配置文件设置一个新变量的原因。

Note 2: if you are running a web application, instead of using this intermediate file, filter this value in your web.xml

注意 2:如果您正在运行 Web 应用程序,请在您的 web.xml 中过滤此值,而不是使用此中间文件

<context-param>
    <param-name>spring.profiles.active</param-name>
    <param-value>${mySpringProfile}</param-value>
</context-param>

Note 3: This is actually a bad practice, and you should set the profile at runtime with a system property

注意 3:这实际上是一种不好的做法,您应该在运行时使用系统属性设置配置文件

回答by Eugene

There is a more elegant way to switch between 2 maven+spring profiles simultaneously.

有一种更优雅的方式可以同时在 2 个 maven+spring 配置文件之间切换。

First, add profiles to POM (pay attention - maven+spring profile is activated by single system variable):

首先,向 POM 添加配置文件(注意 - maven+spring 配置文件由单个系统变量激活):

<profiles>
    <profile>
        <id>postgres</id>
        <activation>
            <activeByDefault>true</activeByDefault>
            <property>
                <name>spring.profiles.active</name>
                <value>postgres</value>
            </property>
        </activation>
        <dependencies>
            <dependency>
                <groupId>postgresql</groupId>
                <artifactId>postgresql</artifactId>
                <version>9.1-901.jdbc4</version>
            </dependency>
        </dependencies>
    </profile>
    <profile>
        <id>h2</id>
        <activation>
            <property>
                <name>spring.profiles.active</name>
                <value>h2</value>
            </property>
        </activation>           
        <dependencies>
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
                <version>1.4.191</version>
            </dependency>
        </dependencies>
    </profile>
</profiles>

Second, set default profile for spring (for maven it is already set in POM). For web application, I inserted following lines to web.xml:

其次,为 spring 设置默认配置文件(对于 maven,它已经在 POM 中设置了)。对于 Web 应用程序,我插入了以下几行web.xml

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

Third, add profile-dependent beans to your config. In my case (XML config), it is:

第三,将依赖于配置文件的 bean 添加到您的配置中。就我而言(XML 配置),它是:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="mainDataSource" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
    <property name="jpaProperties" ref="hibProps"/>
    <property name="packagesToScan">
        <list>
            <value>my.test.model</value>
        </list>
    </property>
</bean>
...
<beans profile="postgres">
    <bean name="mainDataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.postgresql.Driver" />
        <property name="url" value="jdbc:postgresql://127.0.0.1:5432/webchat" />
        <property name="username" value="postgres" />
        <property name="password" value="postgres" />
    </bean>
</beans>

<beans profile="h2">
    <bean name="mainDataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.h2.Driver" />
        <property name="url" value="jdbc:h2:file:./newsdb;INIT=RUNSCRIPT FROM 'classpath:init.sql';TRACE_LEVEL_FILE=0" />
        <property name="username" value="sa" />
        <property name="password" value="" />
    </bean>
</beans>

Now it is possible to:

现在可以:

  • Run my web-app on Postgres DB with mvn jetty:runor mvn jetty:run -Dspring.profiles.active=postgrescommands
  • Run my web-app on H2 DB with mvn clean jetty:run -Dspring.profiles.active=h2
  • 使用mvn jetty:runmvn jetty:run -Dspring.profiles.active=postgres命令在 Postgres DB 上运行我的网络应用程序
  • 在 H2 DB 上运行我的网络应用程序 mvn clean jetty:run -Dspring.profiles.active=h2

回答by Jim Tough

I'm currently building a small webapp that (due to reasons beyond my control) has to be capable of running on an old server/container that only supports Servlet 2.5 and Java 6. There is also a requirement for the webapp configuration to be completely self-contained, so even system variables and/or JVM parameters cannot be used. The administrator just wants a .war file for each environment that can be dropped into the container for deployment.

我目前正在构建一个小型 webapp(由于我无法控制的原因)必须能够在仅支持 Servlet 2.5 和 Java 6 的旧服务器/容器上运行。还要求 webapp 配置完全独立的,因此甚至不能使用系统变量和/或 JVM 参数。管理员只需要每个环境的 .war 文件,可以将其放入容器中进行部署。

I'm using Spring 4.x in my webapp. This is how I configured my application such that the active Maven profile is used to set the active Spring 4.x profile.

我在我的 web 应用程序中使用 Spring 4.x。这就是我如何配置我的应用程序,以便使用活动的 Maven 配置文件来设置活动的 Spring 4.x 配置文件。



pom.xml file changes

pom.xml 文件更改

I added the following bits to my POM file. My POM is using model version 4.0.0 and I'm running Maven 3.1.x when I do my builds.

我将以下位添加到我的 POM 文件中。我的 POM 使用模型版本 4.0.0,我在构建时运行 Maven 3.1.x。

<modelVersion>4.0.0</modelVersion>

...

<profiles>
    <profile>
        <id>dev</id>
        <activation>
            <!-- Default to dev so we avoid any accidents with prod! :) -->
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <!-- This can be a single value, or a comma-separated list -->
            <spring.profiles.to.activate>dev</spring.profiles.to.activate>
        </properties>
    </profile>
    <profile>
        <id>uat</id>
        <properties>
            <!-- This can be a single value, or a comma-separated list -->
            <spring.profiles.to.activate>uat</spring.profiles.to.activate>
        </properties>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <!-- This can be a single value, or a comma-separated list -->
            <spring.profiles.to.activate>prod</spring.profiles.to.activate>
        </properties>
    </profile>
</profiles>

...

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.6</version>
            <configuration>
                <webResources>
                    <webResource>
                        <filtering>true</filtering>
                        <directory>src/main/webapp</directory>
                        <includes>
                            <include>**/web.xml</include>
                        </includes>
                    </webResource>
                </webResources>
                <failOnMissingWebXml>true</failOnMissingWebXml>
            </configuration>
        </plugin>
        ...
    </plugins>
</build>


web.xml file changes

web.xml 文件更改

<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Setup for root Spring context
-->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring-core-config.xml</param-value>
</context-param>
<!--
Jim Tough - 2016-11-30
Per Spring Framework guide: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-environment

...profiles may also be activated declaratively through the spring.profiles.active 
property which may be specified through system environment variables, JVM system 
properties, servlet context parameters in web.xml, or even as an entry in JNDI.
-->
<context-param>
    <param-name>spring.profiles.active</param-name>
    <param-value>${spring.profiles.to.activate}</param-value>
</context-param>
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->


Now I can create Java-based configuration classes like the one below that will only be used when a particular Spring profile is active.

现在我可以创建像下面这样的基于 Java 的配置类,它只会在特定的 Spring 配置文件处于活动状态时使用。

@Configuration
@Profile({"dev","default"})
@ComponentScan
@EnableTransactionManagement
@EnableSpringDataWebSupport
public class PersistenceContext {
    // ...
}

回答by Sergio Sánchez Sánchez

The first thing you need is two properties files for keeping your configurations. The names of the files should match with the pattern application-{custom_suffix}.properties. Create them in the src/main/resources directory of your Maven project, next to the main application.properties file, which you're going to use later to activate one of the others and to hold values shared by both profiles.

您首先需要的是两个用于保存配置的属性文件。文件的名称应与模式 application-{custom_suffix}.properties 匹配。在 Maven 项目的 src/main/resources 目录中,在主 application.properties 文件旁边创建它们,稍后您将使用该文件来激活其他文件之一并保存两个配置文件共享的值。

Then it's time to modify your pom.xml. You need to define a custom property in each of your Maven profiles and set their values to match with suffixes of corresponding properties files that you want to load with a particular profile. The following sample also marks the first profile to run by default, but it's not mandatory.

然后是时候修改你的 pom.xml 了。您需要在每个 Maven 配置文件中定义一个自定义属性,并将它们的值设置为与要使用特定配置文件加载的相应属性文件的后缀相匹配。以下示例还标记了默认情况下要运行的第一个配置文件,但这不是强制性的。

<profile>
    <id>dev</id>
    <properties>
        <activatedProperties>dev</activatedProperties>
    </properties>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
</profile>
<profile>
    <id>release</id>
    <properties>
        <activatedProperties>release</activatedProperties>
    </properties>
</profile>

Next, in the build section of the same file, configure filtering for the Resources Plugin. That will allow you to insert properties defined in the previous step into any file in the resources directory, which is the subsequent step.

接下来,在同一文件的构建部分,为资源插件配置过滤。这将允许您将上一步中定义的属性插入到资源目录中的任何文件中,这是后续步骤。

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
    …
</build>

Finally, add the following line to the application.properties.

最后,将以下行添加到 application.properties。

spring.profiles.active=@activatedProperties@

When the build is run, the Resources Plugin will replace the placeholder with the value of the property defined in the active Maven profile. After starting your application, the Spring framework will load the appropriate configuration file based on the name of the active Spring profile, which is described by the value of the spring.profiles.active property. Note that Spring Boot 1.3 replaced the default Resources Plugin syntax for filtered values and uses @activatedProperties@instead of ${activatedProperties}notation.

当构建运行时,资源插件将用活动 Maven 配置文件中定义的属性值替换占位符。启动应用程序后,Spring 框架将根据活动 Spring 配置文件的名称加载适当的配置文件,该名称由 spring.profiles.active 属性的值描述。请注意,Spring Boot 1.3 替换了过滤值的默认资源插件语法,并使用@activatedProperties@${activatedProperties}符号代替。

It worked to perfection. Hope this can help you.

它工作到完美。希望这可以帮到你。

回答by xxg

Add placeholder ${activeProfile}in web.xml:

${activeProfile}在 web.xml 中添加占位符:

<context-param>
  <param-name>spring.profiles.active</param-name>
  <param-value>${activeProfile}</param-value>
</context-param>

Set properties in pom.xml for each profile:

在 pom.xml 中为每个配置文件设置属性:

<profiles>
  <profile>
    <id>profile1</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
      <activeProfile>profile1</activeProfile>
    </properties>
  </profile>
  <profile>
    <id>profile2</id>
    <properties>
      <activeProfile>profile2</activeProfile>
    </properties>
  </profile>
</profiles>

Add maven-war-pluginand set <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>to replace the placeholder when running mvn package -Pprofile1or mvn package -Pprofile2:

添加maven-war-plugin并设置<filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>以在运行时替换占位符mvn package -Pprofile1mvn package -Pprofile2

<build>
  <plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>3.2.2</version>
    <configuration>
      <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
    </configuration>
  </plugin>
</build>

回答by Sayadi

For a Spring Boot application, one can add a property in the Maven profile in pom.xmland then reference that property in application.properties.

对于 Spring Boot 应用程序,可以在 Maven 配置文件中添加一个属性pom.xml,然后在application.properties.

Add Maven profiles to pom.xmlwith, for example, a property called spring.profile.from.maven:

将 Maven 配置文件添加到pom.xml,例如,名为 的属性spring.profile.from.maven

<profiles>
    <profile>
        <id>postgres</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <spring.profile.from.maven>postgres</spring.profile.from.maven>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>org.postgresql</groupId>
                <artifactId>postgresql</artifactId>
                <scope>runtime</scope>
            </dependency>
        </dependencies>
    </profile>
    <profile>
        <id>noDb</id>
        <properties>
            <spring.profile.from.maven>noDb</spring.profile.from.maven>
        </properties>
    </profile>
</profiles>

Reference the Maven property in application.properties:

引用 Maven 属性application.properties

[email protected]@

With this setup, running maven with the postgresMaven profile or with no profile adds the postgresSpring profile to the list of Spring's active profiles, while running maven with the noDbMaven profile adds the noDbSpring profile to the list of Spring's active profiles.

通过此设置,使用postgresMaven 配置文件或不使用配置文件运行 maven会将postgresSpring 配置文件添加到 Spring 的活动配置文件列表中,而使用noDbMaven 配置文件运行 maven会将noDbSpring 配置文件添加到 Spring 的活动配置文件列表中。