maven profile自动切换环境参数的2种方法详解

前言

痛点:

在java开发的过程中,我们经常要面对各种各样的环境,比如开发环境,测试环境,正式环境,而这些环境对项目的需求也不相同。

在此之前,我们往往需要手动去修改相对应的配置文件然后打成war,才能部署到相应的环境上。

但是这样很容易出现问题,因为很容易出现少改或者漏改,造成不必要的麻烦

幻想:

要是有一种东西,能让我们打war的时候指定一个参数,就能自动把项目编译成对应环境的war,那该有多幸福啊!!!

结果:这样的东西还真有,那就是maven-profile

在开发过程中,我们经常会根据不同的环境配置不同的参数,如数据源的ip,username,password、url、秘钥等都会不同,传统方式是在一个配置文件中通过修改properties文件中的参数值或者通过注释解注释来达到目的,这样不仅容易出错,还浪费不必要的时间,更重要的是把代码发布到测试环境或者生产环境还容易忘记改。为解决这种问题,maven提供了一种解决方案,就是profile。

下图为传统方式,需要来回的注释和解注释

profile定义的位置

  • 针对于特定项目的profile配置我们可以定义在该项目的pom.xml中。
  • 针对于特定用户的profile配置,我们可以在用户的settings.xml文件中定义profile。该文件在用户家目录下的“.m2”目录下。
  • 全局的profile配置。全局的profile是定义在Maven安装目录下的“conf/settings.xml”文件中的。

filter方式实现

第一步:分别定义application-dev.properties、application-test.properties、application-pro.properties三个文件

application-dev.properties

env.jdbc.username=dev
env.jdbc.password=123456

application-test.properties

env.jdbc.username=test
env.jdbc.password=888888

application-pro.properties

env.jdbc.username=root
env.jdbc.password=666666

第二步:定义总的属性文件application.properties,该文件中的值去引用application-<env>.properties中的key

application.properties

// 引用application-<env>中的key
jdbc.username=${env.jdbc.username}
jdbc.password=${env.jdbc.password}

# 公共配置
salt=123456789

第三步:配置profile

<profiles>
 <profile>
 <!-- 开发环境 -->
 <id>dev</id>
 <properties>
 <env>dev</env>
 </properties>
 <activation>
 <!-- 设置默认激活这个配置 -->
 <activeByDefault>true</activeByDefault>
 </activation>
 </profile>
 <profile>
 <!-- 测试环境 -->
 <id>test</id>
 <properties>
 <env>test</env>
 </properties>
 </profile>
 <profile>
 <!-- 发布环境 -->
 <id>pro</id>
 <properties>
 <env>pro</env>
 </properties>
 </profile>
 </profiles>

第四步:配置filter和resource

${env}就是在mvn package -P <env>的名字,这样就告诉application.properties中应用的key是那个属性文件的key了

<build>
 <finalName>profile-app</finalName>
 <!-- 定义了变量配置文件的地址 -->
 <filters>
 <filter>src/main/resources/config/application/application-${env}.properties</filter>
 </filters>

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

 <plugins>
 <plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-war-plugin</artifactId>
 </plugin>
 </plugins>
 </build>

打包运行

// 如果不指定环境,默认是activeByDefault=true的环境,当前是指开发环境
mvn package

// 打包指定的环境通过-P 参数,注意p是大写的
mvn package -P <env>

从mvn packege -P test运行的结果中可以看到生成的target目录下classes/application.perperties中的jdbc.username和jdbc.password 就是application-test.properties中配置的env.jdbc.username和env.jdbc.password的值。

在spring中如果要使用属性配置文件,直接引入这个总的配置文件即可,其他的环境配置文件的使命已经结束了。
<context:property-placeholder location="classpath:application.properties"/>

实现原理:

在pom.xml中为每个不同的环境定义不同的profile,每个profile都有一个环境名称,然后为不同环境定义不同的配置文件(如application-<env>.properties), 再定义一个总的属性文件(如application.properties), 然后让application.properties的value去引用application-<env>.properties中对应的key,在打包时指定要打包的环境的名称即可,这样application.properties中的key的值就是相对应环境application-<env>.properties对应的值了。

多resource实现方式

步骤

第一步:在src/main/resource创建一个env目录,再创建各个环境的子目录,再再各个环境子目录下创建名为config.properties的文件,每个键相同,值不同。
env/dev/config.properties

jdbc.username=dev
jdbc.password=123456

env/test/config.properties

jdbc.username=test
jdbc.password=888888

env/pro/config.properties

jdbc.username=root
jdbc.password=666666

第二步:创建一个与环境无关的application.properties

application.properties

# 公共配置
salt=123456789

第三步:配置profiles

<profiles>
 <profile>
 <!-- 开发环境 -->
 <id>dev</id>
 <properties>
 <env>dev</env>
 </properties>
 <activation>
 <!-- 设置默认激活这个配置 -->
 <activeByDefault>true</activeByDefault>
 </activation>
 </profile>
 <profile>
 <!-- 测试环境 -->
 <id>test</id>
 <properties>
 <env>test</env>
 </properties>
 </profile>
 <profile>
 <!-- 发布环境 -->
 <id>pro</id>
 <properties>
 <env>pro</env>
 </properties>
 </profile>
</profiles>

第四步:配置resource

<build>
 <finalName>profile-app</finalName>
 <!-- 定义了变量配置文件的地址 -->
 <resources>
 <resource>
 <directory>src/main/resources</directory>
 <excludes>
 <exclude>env/dev/*</exclude>
 <exclude>env/test/*</exclude>
 <exclude>env/pro/*</exclude>
 </excludes>
 <filtering>true</filtering>
 </resource>
 <resource>
 <directory>src/main/resources/env/${env}</directory>
 <includes>
 <include>*.*</include>
 <include>**/*.xml</include>
 <include>**/*.properties</include>
 </includes>
 <filtering>true</filtering>
 </resource>
 </resources>

 <plugins>
 <plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-war-plugin</artifactId>
 </plugin>
 </plugins>
</build>

第五步:运行 mvn package -P test

如果经常使用mvn package -P <env>可以在idea中配置一些maven, 步骤为:Edit Configurations… —– + —- Maven —- 分别为每个环境添加maven 命令,以后双击Run Configureations中的任意一个就是相当于运行mvn package -P <env>命令了

两种方式比较

filter方式会把所有的application-dev.properties、application-test.properties、application-pro.properties文件都会打包进去,而且此种方式只能针对属性文件,如果有其他文件(如.xml)也根据不同的环境有不同的配置,这种方式是不好处理。

多resource方式在打包时只打包指定环境的配置文件,可以将各种文件放到各自的环境文件夹中,在打包的时候会将整个文件夹都打包进去。推荐此种方式

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • Maven管理SpringBoot Profile详解

    1. Spring Profile Spring可使用Profile绝对程序在不同环境下执行情况,包含配置.加载Bean.依赖等. Spring的Profile一般项目包含:dev(开发), test(单元测试), qa(集成测试), prod(生产环境).由spring.profiles.active属性绝定启用的profile. SpringBoot的配置文件默认为 application.properties(或yaml,此外仅心properties配置为说明).不同Profile下的配置

  • Java随手笔记8之包、环境变量和访问控制及maven profile实现多环境打包

    一.java中的包 Java利用包来组织代码,一来使大型项目的代码结构清晰,二来包是一个命名空间的划分,即不同包中可以有相同名字的类,只需在在类名前加上包名即可区分它们. Package xxx 必须位于java文件除了注释以外的第一行,用来指明当前文件中的类属于哪一个包,如果没有package语句,则该文件中的类都属于默认包. Import xxx用来在当前java文件中导入不属于当前包中的类,从而可以在当前文件中使用它们. 二.java中的环境变量 1.path 环境变量其实就是一组变量(废

  • maven profile自动切换环境参数的2种方法详解

    前言 痛点: 在java开发的过程中,我们经常要面对各种各样的环境,比如开发环境,测试环境,正式环境,而这些环境对项目的需求也不相同. 在此之前,我们往往需要手动去修改相对应的配置文件然后打成war,才能部署到相应的环境上. 但是这样很容易出现问题,因为很容易出现少改或者漏改,造成不必要的麻烦 幻想: 要是有一种东西,能让我们打war的时候指定一个参数,就能自动把项目编译成对应环境的war,那该有多幸福啊!!! 结果:这样的东西还真有,那就是maven-profile 在开发过程中,我们经常会根

  • Mybatis 逆向工程的三种方法详解

    Mybatis 逆向工程   逆向工程通常包括由数据库的表生成 Java 代码 和 通过 Java 代码生成数据库表.而Mybatis 逆向工程是指由数据库表生成 Java 代码.   Mybaits 需要程序员自己编写 SQL 语句,但是 Mybatis 官方提供逆向工程可以针对单表自动生成 Mybaits 执行所需要的代码,包括 POJO.Mapper.java.Mapper.xml -. 一.通过 Eclipse 插件完成 Mybatis 逆向工程 1. 在线安装 Eclipse 插件  

  • SpringBoot注入配置文件的3种方法详解

    这篇文章主要介绍了SpringBoot注入配置文件的3种方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 方案1:@ConfigurationProperties+@Component 定义spring的一个实体bean装载配置文件信息,其它要使用配置信息是注入该实体bean /** * 将配置文件中配置的每一个属性的值,映射到这个组件中 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配

  • Python开发装包八种方法详解

    目录 1. 使用 easy_install 2. 使用 pip install 3. 使用 pipx 4. 使用 setup.py 5. 使用 yum 6. 使用 pipenv 7. 使用 poetry 8. 使用 curl + 管道 1. 使用 easy_install easy_install 这应该是最古老的包安装方式了,目前基本没有人使用了.下面是 easy_install 的一些安装示例 # 通过包名,从PyPI寻找最新版本,自动下载.编译.安装 $ easy_install pkg_

  • Java 不使用第三方变量交换两个变量值的四种方法详解

    目录 变量本身交换数值 算术运算 指针地址操作 位运算 简单总结 哈喽,大家好,我是阿Q.前几天有个小伙伴去面试,被面试官的一个问题劝退了:请说出几种不使用第三方变量交换两个变量值的方法. 问题有点绕,好不容易缕清了面试官的问题,却发现答不上来.一时间尴尬无比,只能硬着头皮说不会. 遇到交换变量值的问题,通常我们的做法是:定义一个新的变量,借助它完成交换. 代码如下: t = a; a = b; b = t; 但问题的重点是"不使用第三方变量",那就变得"可爱"起来

  • Java实现Excel转PDF的两种方法详解

    目录 一.使用spire转化PDF 1.使用spire将整个Excel文件转为PDF 2.指定单个的sheet页转为PDF 二.使用jacob实现Excel转PDF(推荐使用) 1.环境准备 2.执行导出PDF 使用具将Excel转为PDF的方法有很多,在这里我给大家介绍两种常用的方法,分别应对两种不一样的使用场景,接下来我在springboot环境下给大家做一下演示! 一.使用spire转化PDF 首先介绍一种比较简单的方法,这种方法可以使用短短的几行代码就可以将我们的Excel文件中的某一个

  • SpringBoot处理接口幂等性的两种方法详解

    目录 1. 接口幂等性实现方案梳理 1.1 基于 Token 1.2 基于请求参数校验 2. 基于请求参数的校验 在上周发布的 TienChin 项目视频中,我和大家一共梳理了六种幂等性解决方案,接口幂等性处理算是一个非常常见的需求了,我们在很多项目中其实都会遇到.今天我们来看看两种比较简单的实现思路. 1. 接口幂等性实现方案梳理 其实接口幂等性的实现方案还是蛮多的,我这里和小伙伴们分享两种比较常见的方案. 1.1 基于 Token 基于 Token 这种方案的实现思路很简单,整个流程分两步:

  • JavaScript中数组去重常用的五种方法详解

    目录 1.对象属性(indexof) 2.new Set(数组) 3.new Map() 4.filter() + indexof 5.reduce() + includes 补充 原数组 const arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}]; 1.对象属性(indexof) 利用对象属性key排除重复项 遍历数组,每次判断新数组中是否存在该属性,不存在就存储在新数组中 并把数组元素作为key,最后返

  • Springboot配置返回日期格式化五种方法详解

    目录 格式化全局时间字段 1.前端时间格式化(不做无情人) 2.SimpleDateFormat格式化(不推荐) 3.DateTimeFormatter格式化(不推荐) 4.全局时间格式化(推荐) 实现原理分析 5.部分时间格式化(推荐) 总结 应急就这样 格式化全局时间字段 在yml中添加如下配置: spring.jackson.date-format=yyyy-MM-dd HH:mm:ss 或者 spring: jackson: ## 格式为yyyy-MM-dd HH:mm:ss date-

  • 基于ScheduledExecutorService的两种方法(详解)

    开发中,往往遇到另起线程执行其他代码的情况,用java定时任务接口ScheduledExecutorService来实现. ScheduledExecutorService是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响. 注意,只有当调度任务来的时候,ScheduledExecutorService才会真正启动一个线程,其余时间ScheduledExecutorService都是处于轮询任务的状态. 1.scheduleAtFix

随机推荐