在Maven和Spring中,都有profile这个概念。profile是用于区分各种环境的,例如开发环境、测试环境、正式环境等。Maven的profile用于在打包时根据指定环境替换不同环境的配置文件配置,如数据库配置。Spring的Profile可以用于在不同的环境下加载不同的bean,例如@Profile注解。两者一个是Maven编译和打包时生效,另一个是运行时生效,默认是没有关联的,本文会分别介绍非Spring Boot项目和Spring Boot项目整合Maven profile。

Maven profile配置

pom.xml中,可以配置testproduct两个profile,分别对应测试环境和正式环境。这里也可以根据具体情况自定义。

<profiles><profile><id>test</id>...</profile><profile><id>product</id>...</profile>
</profiles>

此时,运行mvn package -Ptest就会使用id为test的profile内的配置打包,mvn package -Pproduct就是用来打正式环境包的命令。

Spring Framework(非Spring Boot)整合Maven profile

Spring Framework如何启用一个profile

Spring启用某个profile有多种方式(摘自官方文档:https://docs.spring.io/spring/docs/5.1.5.RELEASE/spring-framework-reference/core.html#beans-definition-profiles-enable ):

Activating a profile can be done in several ways, but the most straightforward is to do it programmatically against the Environment API which is available through an ApplicationContext.
In addition, you can also declaratively activate profiles 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.

总结一下有以下几种方式:

  • 通过代码设置:ApplicationContext.getEnvironment().setActiveProfiles("yourProfile")
  • 通过系统环境变量spring.profiles.active值来设置
  • 通过JVM系统属性spring.profiles.active值来设置
  • 通过web.xml中的context-param来设置

为了便于跟Maven整合,我们使用web.xml来设置Spring profile,如下:

<context-param><param-name>spring.profiles.active</param-name><param-value>product</param-value>
</context-param>

以上配置会启用Spring的product profile,即正式环境。

Spring Framework profile整合Maven profile

如果想要整合Maven profile和Spring Framework profile,需要在Maven打包时对web.xml中的spring.profiles.active值进行替换,可以在web.xml中配置一个占位符${activeProfile}

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

pom.xml配置maven-war-plugin

<!-- 打war包时替换占位符 -->
<build><plugin><artifactId>maven-war-plugin</artifactId><version>3.2.2</version><configuration><filteringDeploymentDescriptors>true</filteringDeploymentDescriptors></configuration></plugin>
</build><!-- 默认的maven profile -->
<properties><activeProfile>dev</activeProfile>
</properties><profiles><profile><id>test</id><properties><activeProfile>test</activeProfile></properties></profile><profile><id>product</id><properties><activeProfile>product</activeProfile></properties></profile>
</profiles>

<filteringDeploymentDescriptors>true表示过滤Deployment Descriptor并将文件中的占位符替换为pom.xml中对应的<properties>值,Deployment Descriptor即部署描述符,指的就是web.xml (参考维基百科:https://zh.wikipedia.org/wiki/部署描述符 )。

以上配置完成后,再通过mvn package -Ptestmvn package -Pproduct打包后,再解压war包,可以看到web.xml中原有的

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

被替换为了Maven中对应的profile,例如mvn package -Pproduct打包后web.xml内容:

<context-param><param-name>spring.profiles.active</param-name><param-value>product</param-value>
</context-param>

以上就完成了Maven profile和Spring profile的整合。

兼容jetty-maven-plugin

如果恰好在项目中使用到jetty-maven-plugin用于开发环境调试,那么在web.xml配置占位符${activeProfile}后,通过mvn jetty:run启动应用时会Spring框架会报错:

Could not resolve placeholder 'activeProfile' in string value "${activeProfile}"

这是因为运行mvn jetty:run命令时插件并没有打war包,而是直接使用源码中的web.xml,此时占位符${activeProfile}未被maven-war-plugin替换,所以Spring框架会报错。

参考文档:https://www.eclipse.org/jetty/documentation/9.4.x/jetty-maven-plugin.html#jetty-run-goal

解决方法一

使用mvn jetty:run-warmvn jetty:run-exploded命令替代mvn jetty:run,这两个命令会先用maven-war-plugin打好war包后再运行,此时占位符${activeProfile}已被替换为Maven的profile。

但是这种方案会带来一个问题:由于这种方式需要先打war包再运行,开发时项目中资源(例如html、jsp)修改后就不会实时生效,而是需要重新打包启动,不便于调试。

解决方法二(推荐)

这种方案还是使用mvn jetty:run命令,只需要给jetty-maven-plugin插件添加一个名为activeProfile的系统属性,让Spring框架来解析web.xml中的${activeProfile}

<plugin><groupId>org.eclipse.jetty</groupId><artifactId>jetty-maven-plugin</artifactId><version>9.2.10.v20150310</version><configuration><webApp><contextPath>/</contextPath></webApp><systemProperties><systemProperty><name>activeProfile</name><value>${activeProfile}</value></systemProperty></systemProperties></configuration>
</plugin>

参考文档:https://www.eclipse.org/jetty/documentation/9.4.x/jetty-maven-plugin.html#setting-system-properties

Spring Boot整合Maven profile

如果项目采用的框架是Spring Boot而不是直接使用Spring Framework,那么Spring Boot的profile可以在resources目录下的application.propertiesapplication.yml文件中指定,以application.properties为例:

spring.profiles.active=product

要想整合Maven profile只需要改为@activeProfile@占位符即可:

spring.profiles.active=@activeProfile@

仅需要这一行配置就完成了Spring Boot profile整合Maven profile,非常方便。此时可以尝试mvn package -Ptestmvn package -Pproduct命令打包,安装包内的文件中@activeProfile@占位符已被替换。

Spring Boot整合Maven profile原理

Spring Boot项目中一般都会加上spring-boot-starter-parent

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>${spring.boot.version}</version>
</parent>

可以查看spring-boot-starter-parent的pom.xml文件,里面包含maven-resources-plugin

<plugin><artifactId>maven-resources-plugin</artifactId><configuration><delimiters><delimiter>${resource.delimiter}</delimiter></delimiters><useDefaultDelimiters>false</useDefaultDelimiters></configuration>
</plugin>

${resource.delimiter}定义的值是@

<resource.delimiter>@</resource.delimiter>

这样maven-resources-plugin插件会将application.propertiesapplication.yml文件中的@activeProfile@替换为pom.xml中对应profile的值。

至于为什么Spring Boot要使用@..@而不是Maven默认的${..}作为占位符的符号,官方文档也给出了解释,以下摘自:https://docs.spring.io/spring-boot/docs/2.0.4.RELEASE/reference/htmlsingle/#using-boot-maven

Note that, since the application.properties and application.yml files accept Spring style placeholders (${…​}), the Maven filtering is changed to use @…@ placeholders. (You can override that by setting a Maven property called resource.delimiter.)

因为Spring Boot框架本身也用${..}作为占位符,Maven插件maven-resources-plugin如果还使用相同的占位符,那么可能会导致一些冲突,所以spring-boot-starter-parentmaven-resources-plugin的占位符改为@..@

参考文档

  • Spring Framework: Activating a Profile
  • Spring Boot: Maven
  • Jetty Maven Plugin
  • 维基百科:部署描述符(Deployment Descriptor)

原文链接

https://xxgblog.com/2016/06/01/maven-spring-profile/

Maven profile整合Spring profile相关推荐

  1. Springboot使用Maven Profile和Spring Profile进行多环境配置

    Springboot使用Maven Profile和Spring Profile进行多环境配置 目的 在实际的项目上,一般会分三种环境dev.test.prod来方便我们的开发和部署,要求我们在开发的 ...

  2. Springboot使用Maven项目使用 Profiles和Spring Profile进行多环境配置 动态激活指定

    最终效果:①:IDEA右边"maven"的工具栏 ②:项目配置的多环境选项入口[默认:dev] ③:项目配置的多环境配置文件 ④:选择②操作后编译生成的配置文件[去除其它环境配置文 ...

  3. Maven中的profile和spring boot中的profile进行结合

    2019独角兽企业重金招聘Python工程师标准>>> 有一些应用,采用了spring boot和spring boot profile.然后想把maven 中的profile和sp ...

  4. maven spring profile 协同

    请在网上查相关的使用情景,这里直接上要点.另外,可能不只一种方法,但这里只有一种. 1.POM.XML片段,使web.xml文件中有关活跃spring profile的内容可以被maven自动替换 & ...

  5. aspect spring_使用Aspect和Spring Profile进行电子邮件过滤

    aspect spring 在Web应用程序开发期间,经常需要发送电子邮件. 但是,有时数据库中会包含来自生产的数据,并且存在在电子邮件测试执行期间向真实客户发送电子邮件的风险. 这篇文章将解释如何避 ...

  6. Spring Profile模式示例

    最近,我们介绍了Spring Profiles的概念. 此概念是针对不同部署环境的轻松配置区分符. 直接的用例(已提出)是对相关类进行注释,以便Spring根据活动的配置文件加载适当的类. 但是,这种 ...

  7. 使用Aspect和Spring Profile进行电子邮件过滤

    在Web应用程序开发期间,经常需要发送电子邮件. 但是,有时数据库中会包含来自生产的数据,并且存在在电子邮件测试执行期间向真实客户发送电子邮件的风险. 这篇文章将解释如何避免在没有在发送电子邮件功能中 ...

  8. 补习系列(22)-全面解读 Spring Profile 的用法

    目录 一.简介 二. 区分Bean对象 三. 设置Profile 3.1 WebApplicationInitializer接口 3.2 通过 web.xml定义 3.3 JVM启动参数 3.4 环境 ...

  9. spring boot 构建docker镜像,运行指定spring profile

    #本文基于maven构建的spring boot项目,打包docker镜像需要安装docker 1.pom.xml添加docker打包插件 <plugin><groupId>c ...

最新文章

  1. mysql 5.6 互为主从_mysql5.6主从同步,互为主从配置
  2. mysql数据库ab复制_mysql replication(AB复制)
  3. 2020对于音视频行业意味着什么?
  4. linux安装Git依赖的包出错,技术|Linux有问必答:如何在Linux上安装Git
  5. arthas用的好好的,写个lambda表达式就跪了?该咋解决?
  6. 两个list取交集_Java基础面试题-说说你知道的几个Java集合类:list、set、queue、map...
  7. Oracle中insert into select和select into from的用法
  8. Virtual Box手动激活OEM版Win7
  9. Vue3和Vue2的一些区别
  10. ICC图文流程——(六)可造性设计Chip finishing
  11. 实验四——DPCM编码(1bit、2bit、4bit、8bit量化)
  12. 【网络安全】文件包含漏洞总结
  13. 阿里云Maven仓库地址及设置
  14. VMware设置虚拟机与物理主机处于同一网段,桥接模式
  15. 通过蓝点无限的学习,对UWB实现的过程以及对UWB连接WIFI的遇到的问题进行复盘
  16. java 获取周六周日_JS实现获取当前所在周的周六、周日示例分析
  17. transition动画效果
  18. 博图程序需要手动同步_博图新手使用说明
  19. Sun公司的操作系统:Solaris简介
  20. 一物一码(6): 一物一码之【开展一物一码营销活动基本流程2,设计开发部署,生产包装,活动上线】

热门文章

  1. iPhone变砖-记录一次无限菊花圈的不刷机抢救过程
  2. 软件测试就业难,没有面试机会,常年外包,人到30岁+还在岗位或工作的选择上身不由己,如何破局?
  3. 一、前端稳定性规约该如何制定
  4. Spring Cloud Config配置文件加解密
  5. 铺垫了很久,爱奇艺终究还是做了涨价领头羊
  6. AppConfig增加IsEnumToInt配置
  7. “毒舌”专家解析案例Part12—康师傅方便面品牌追踪
  8. sql中如何计算百分比
  9. Oracle 11g 关于权限DBA和SYSDBA的区别是什么
  10. Android 仿美团外卖底部顶起 lottie 封装