基于Maven的profiles多环境配置

news2025/1/18 10:43:36

一个项目通常都会有多个不同的运行环境,例如开发环境,测试环境、生产环境等。而不同环境的构建过程很可能是不同的,例如数据源配置、插件、以及依赖的版本等。每次将项目部署到不同的环境时,都需要修改相应的配置,这样重复的工作,不仅浪费劳动力,还容易出错。为了解决这一问题,Maven 引入了 Profile 的概念,通过它可以为不同的环境定制不同的构建过程。

目录

    • 一、Profile 的类型
    • 二、声明 Profile
    • 三、需要注意的地方
    • 四、激活 Profile
      • 1、命令行激活
      • 2、settings.xml 文件显示激活
      • 3、系统属性激活
      • 4、操作系统环境激活
      • 5、文件存在与否激活
      • 6、默认激活
      • 7、根据jdk版本激活
      • 8、idea当中指定profiles
    • 五、实战中多环境配置的几种方式
      • 1、利用antrun插件copy配置文件
      • 2、利用spring提供的profiles.active
      • 3、直接将配置放到pom当中

一、Profile 的类型

Profile 可以分为 3 个类型,它们的作用范围也各不相同。

关于Per User有的电脑是没有的,他是idea不配置maven情况下的一个默认maven配置,如果idea配置了maven可能会没有,直接忽略即可。

二、声明 Profile

Maven 通过 profiles 元素来声明一组 Profile 配置,该元素下可以包含多个 profile 子元素,每个 profile 元素表示一个 Profile 配置。每个 profile 元素中通常都要包含一个 id 子元素,该元素是调用当前 Profile 的标识。

<profiles>
    <profile>
        <id>profile id</id>
        ....
    </profile>

    <profile>
        <id>profile id</id>
        ....
    </profile>
</profiles>

除此之外,Profile 中还可以声明一些其他的 POM 元素,但不同位置的 Profile 所能声明的 POM 元素也是不同的。

  1. 在 pom.xml 中声明的 Profile,由于其能够随着 pom.xml 一起存在,所以它能够修改或增加很多 POM 元素,其中常用的元素如下表:
  2. 在 setting.xml 中声明的 Profile 是无法保证能够随着 pom.xml 一起被分发的,因此 Maven 不允许用户在该类型的 Profile 修改或增加依赖或插件等配置信息,它只能声明以下范围较为宽泛的元素:
    • repositories:仓库配置。
    • pluginRepositories:插件仓库配置。
    • properties:键值对,该键值对可以在 pom.xml 中使用。

三、需要注意的地方

我们所做的示例当中可能会经常修改pom.xml,有时候修改的pom.xml并没有生效,或者是我们新增了配置文件,然后并没有生效。

四、激活 Profile

构建项目的时候,可以通过多种方式激活 Profile,以实现不同环境使用不同的配置,执行不同的构建过程。

Profile 可以通过以下 6 种方式激活:

  • 命令行激活
  • settings.xml 文件显示激活
  • 系统属性激活
  • 操作系统环境激活
  • 文件存在与否激活
  • 默认激活

下面我们以一个 Maven 项目为例,分别对以上 6 种激活方式进行介绍。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.12</version>
		<relativePath/>
	</parent>
	<groupId>com.gzl.cn</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>demo</description>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
	<profiles>
		<!-- dev -->
		<profile>
            <id>dev</id>
            <properties>
                <username>zhangsan</username>
                <profile.active>dev</profile.active>
            </properties>
        </profile>
		<!-- test -->
		<profile>
            <id>test</id>
            <properties>
                <username>lisi</username>
                <profile.active>test</profile.active>
            </properties>
        </profile>
		<!-- on -->
		<profile>
            <id>prod</id>
            <properties>
                <username>wangwu</username>
                <profile.active>prod</profile.active>
            </properties>
        </profile>
    </profiles>

</project>
 

这里我们使用到了@@来取pom当中properties标签的变量值,假如项目没有继承spring-boot-starter-parent,那么取值就应该使用${...}的语法,至于想了解为什么的或者是细节的可以看一下这篇文章,本篇重心是profiles:https://blog.csdn.net/weixin_43888891/article/details/130755755?spm=1001.2014.3001.5501

1、命令行激活

我们可以在命令行中使用 mvn 命令行参数 -P 加上 Profile 的 id 来激活 Profile,多个 id 之间使用逗号隔开。例如,激活 test1 和 test2 两个 Profile, 命令如下:

mvn clean install -Ptest1,test2

打开命令行窗口,跳转到 pom.xml 所在的目录,执行以下 mvn 命令,激活 id 为 test 的 Profile。

mvn clean package -Ptest

这时候查看编译过后的application.properties

2、settings.xml 文件显示激活

在maven安装目录的conf/settings.xml 文件中添加如下配置,激活指定的 Profile。

<activeProfiles>
    <activeProfile>dev</activeProfile>
</activeProfiles>

直接添加到settings.xml最下方即可。

这次执行命令就不需要-P来指定了

mvn clean package

这时候查看编译过后的application.properties

3、系统属性激活

用户可以配置当某个系统属性存在时,激活指定的 Profile。例如,我们在 id 为 prod 的 profile 元素中添加以下配置,表示当系统属性 user 存在,且值等于 prod 时,自动激活该 Profile。

<activation>
      <property>
        <name>user</name>
        <value>prod</value>
    </property>
</activation>

打开命令行窗口,跳转到 pom.xml 所在的目录。执行命令,其中参数 -D 选项用来指定系统临时属性。

mvn clean package -Duser=prod

这时候查看编译过后的application.properties

4、操作系统环境激活

Maven 还可以根据操作系统环境自动激活指定的 Profile。例如,将以下配置(本地计算机操作系统环境信息)添加到 pom.xml 文件中的 id 为 dev的 Profile 中。

<activation>
    <os>
        <name>Windows 10</name>
        <family>Windows</family>
        <arch>amd64</arch>
        <version>10.0</version>
    </os>
</activation>

这时候查看编译过后的application.properties

如果真的涉及到需要根据操作系统来选择对应的配置可以使用这个实现,family标签是操作系统,关于family都有哪些取值可以看源码:https://github.com/sonatype/plexus-utils/blob/f2beca21c75084986b49b3ab7b5f0f988021dcea/src/main/java/org/codehaus/plexus/util/Os.java#L72

5、文件存在与否激活

Maven 可以根据某些文件存在与否,来决定是否激活 Profile。例如,在 id 为 prod 的 Profile 中添加以下配置,该配置表示当 env.prod.properties 文件存在,且 env.test.properties 文件不存在时,激活该 Profile。

<activation>
    <file>
        <exists>./src/main/resources/env.prod.properties</exists>
        <missing>./src/main/resources/env.test.properties</missing>
    </file>
</activation>

6、默认激活

我们可以在声明 Profile 时,指定其默认激活。例如,在 id 为 normal 的 Profile 中添加以下配置,指定该 Profile 默认激活。

<activation>
    <activeByDefault>true</activeByDefault>
</activation>

7、根据jdk版本激活

<activation>
  <jdk>1.4</jdk>
</activation>

8、idea当中指定profiles

maven当中配置了多少profiles在这里都可以看到,而且我们还能选中后启动项目。本质上在这选中指定的profiles然后启动项目应该就是使用的-P命令,只不过idea进行了可视化。

五、实战中多环境配置的几种方式

利用profiles可以完成多环境配置,多环境配置又有很多种配置方式,接下来我会写几个案例供大家参考

1、利用antrun插件copy配置文件

配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.12</version>
		<relativePath/>
	</parent>
	<groupId>com.gzl.cn</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>demo</description>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<resources>
		  <resource>
			<directory>${basedir}/src/main/resources</directory>
			<!--排除配置文件,因为我们是利用的插件生成的application.properties配置文件,那么这些带有-环境的配置文件就可以不用携带了-->
			<excludes>
			  <exclude>**/application*.properties</exclude>
			</excludes>
		  </resource>
		</resources>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
	<profiles>
		<!--test 环境配置  -->
		<profile>
			<id>dev</id>
			<build>
				<plugins>
					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-antrun-plugin</artifactId>
						<version>3.0.0</version>
						<executions>
							<execution>
								<!--生命周期-->
								<phase>compile</phase>
								<!--插件目标-->
								<goals>
									<goal>run</goal>
								</goals>
								<configuration>
									<target>
										<!--输出  -->
										<echo>application-dev.properties,将其配置信息复制到当前项目target\classes\application.properties中</echo>
										<!-- 在 target\calsses 目录下生成application.properties -->
										<!--  application-dev.properties 的内容复制到application.properties中-->
										<copy file="src/main/resources/application-dev.properties"
											  tofile="${project.build.outputDirectory}/application.properties"/>
									</target>
								</configuration>
							</execution>
						</executions>
					</plugin>
				</plugins>
			</build>
		</profile>
		<!--生产环境配置  -->
		<profile>
			<id>prod</id>
			<build>
				<plugins>
					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-antrun-plugin</artifactId>
						<version>3.0.0</version>
						<executions>
							<execution>
								<phase>compile</phase>
								<goals>
									<goal>run</goal>
								</goals>
								<configuration>
									<target>
										<echo>application-prod.properties,将其配置信息复制到当前项目target\classes\application.properties中</echo>
										<!-- 在 target\calsses 目录下生成application.properties -->
										<!--  application-prod.properties 的内容复制到application.properties中-->
										<copy file="src/main/resources/application-prod.properties"
											  tofile="${project.build.outputDirectory}/application.properties"/>
									</target>
								</configuration>
							</execution>
						</executions>
					</plugin>
				</plugins>
			</build>
		</profile>
	</profiles>
</project>

这时候再看会发现target/classes目录下只有我们生成的application.properties,原因是我通过resources标签设置了那两个文件不参与编译和打包。

2、利用spring提供的profiles.active

在这个示例当中我基于上面的示例又新增了一个application.properties

profile.active是变量,可以取xml当中profile当中配置的profile.active标签。

spring.profiles.active=@profile.active@

配置文件当中spring.profiles.active是springboot给我们提供的,假如spring.profiles.active=dev那么application-dev.properties配置文件就会生效。

关于springboot多环境配置:https://blog.csdn.net/weixin_43888891/article/details/110993428

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.12</version>
		<relativePath/>
	</parent>
	<groupId>com.gzl.cn</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>demo</description>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
		<resources>
			<resource>
				<directory>src/main/resources/</directory>
				<filtering>true</filtering>
				<includes>
					<include>**/application.properties</include>
					<include>**/application-${profile.active}.properties</include>
				</includes>
			</resource>
			<resource>
				<directory>src/main/resources/</directory>
				<excludes>
					<exclude>**/*.properties</exclude>
				</excludes>
			</resource>
		</resources>
	</build>
	<profiles>
		<profile>
			<id>dev</id>
			<properties>
				<!-- 自定义节点profile.active-->
				<profile.active>dev</profile.active>
			</properties>
		</profile>
		<profile>
			<id>prod</id>
			<properties>
				<profile.active>prod</profile.active>
			</properties>
		</profile>
	</profiles>
</project>

观察编译路径,当我们生效了prod,那么dev文件就不会被编译打包。这就是我们xml当中配置的resources标签所起到的作用!

可能有的人该好奇了,明明使用spring.profiles.active就足以完成多文件配置了,为什么还要在pom.xml当中配置profile,其实我们这里配置的profile和resources标签就起了一个作用,假如选择dev,那么prod就不参与打包,这样别人通过反编译就看不到我们prod的配置文件了!

3、直接将配置放到pom当中

上面两种都是以多配置文件的形式,这一种是直接将多环境配置都放到pom.xml当中。

所有相关的配置都可以放到properties标签下,然后以@标签@语法在application.properties当中取值

	<profiles>
		<profile>
			<id>dev</id>
			<properties>
				<server.port>8081</server.port>
			</properties>
		</profile>
		<profile>
			<id>prod</id>
			<properties>
				<server.port>9090</server.port>
			</properties>
		</profile>
	</profiles>
</project>

注意我们只是用来测试,所以并没有放很多配置,实际开发当中数据库相关配置都可以在<properties>下添加,然后通过@@取值即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/556709.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

day07_数组初识

数组的概述 数组就是用于存储数据的长度固定的容器&#xff0c;保证多个数据的数据类型要一致。 数组适合做一批同种类型数据的存储 数组中的元素可以是基本数据类型&#xff0c;也可以是引用数据类型。当元素是引用数据类型是&#xff0c;我们称为对象数组。 容器&#xff…

从0开始学C语言的个人心得笔记(10w字)

大学的计算机相关专业第一门教学的计算机语言就是c语言&#xff0c;很多大学生面对从未接触过的计算机语言&#xff0c;可能会觉得很难以上门&#xff0c;从而放弃学习c语言。这篇博客写的主要是个人学习C语言时候的知识总结点&#xff0c;不能保证全部是正确的&#xff0c;如有…

Kafka灵魂28问

第 1 题 Kafka 数据可靠性如何保证&#xff1f; 对于 kafka 来说&#xff0c;以下几个方面来保障消息分发的可靠性&#xff1a; 消息发送的可靠性保障(producer) 消息消费的可靠性保障(consumer) Kafka 集群的可靠性保障&#xff08;Broker&#xff09; 生产者 目前生产者…

Leetcode每日一题——“用队列实现栈”

各位CSDN的uu们你们好呀&#xff0c;好久没有更新本专栏啦&#xff0c;甚是想念&#xff01;&#xff01;&#xff01;今天&#xff0c;小雅兰的学习内容是用队列实现栈&#xff0c;下面&#xff0c;让我们进入Leetcode的世界吧&#xff01;&#xff01;&#xff01; 这是小雅兰…

本地 docker 发布 java 项目,连接本地 redis 配置

1、本地项目 install 相应的 jar 包到 target 目录下&#xff0c;jar 包的路径步骤 2 要填写 2、项目根目录下创建 Dockerfile 文件 # 使用官方的 Java 11 镜像作为基础镜像 FROM openjdk:11-jdk# 设置工作目录 WORKDIR /app# 复制应用程序 JAR 文件到镜像中的 /app 目录下 C…

用LangChain实现一个ChatBlog

文章目录 前言环境一、构建知识库二、将知识库向量化三、召回四、利用LLM做阅读理解五、效果总结 前言 通过本文, 你将学会如何使用langchain来构建一个自己的知识库问答 其实大多数类chatpdf产品的原理都差不多, 我将其简单粗暴地分为以下四步: 构建知识库将知识库向量化召回…

vue diff算法与虚拟dom知识整理(11) 书写patch父级新旧为同一节点 子节点与文字交换逻辑实现

上文我们简单描述了patch处理同一节点的大体逻辑 这次 我们就来看一下text替换的情况 我们更改案例入口文件 src下的 index.js 代码如下 import h from "./snabbdom/h"; import patch from "./snabbdom/patch";const container document.getElementById(…

Maven概念及搭建

1.为什么我们要学习 maven? maven 还未出世的时候&#xff0c;我们有很多痛苦的经历 。 痛点 1&#xff1a; jar 包难以寻找 痛点 2&#xff1a; jar 包依赖的问题 痛点 3&#xff1a; jar 不方便管理 痛点 4&#xff1a;项目编译 2.Maven 简介 Maven 是 Apache 软件基金…

Golang中的管道(channel) 、goroutine与channel实现并发、单向管道、select多路复用以及goroutine panic处理

目录 管道&#xff08;channel&#xff09; 无缓冲管道 有缓冲管道 需要注意 goroutine与channel实现并发 单向管道 定义单向管道 将双向管道转换为单向管道 单向管道作为函数参数 单向管道的代码示例 select多路复用 案例演示 goroutine panic处理 案例演示 管道…

APP服务端架构的演变

大家好&#xff0c;我是易安&#xff01; 早期2013年的时候&#xff0c;随着智能设备的普及和移动互联网的发展&#xff0c;移动端逐渐成为用户的新入口&#xff0c;各个电商平台都开始聚焦移动端App&#xff0c;如今经历了10年的发展&#xff0c;很多电商APP早已经没入历史的洪…

日语文法PPT截图31-45

31 形式名词 とき ところ 作为形式名词的话&#xff0c;一般是要写假名不写汉字的 相对时态 如果是一般时/将来时とき&#xff0c;就是先做后面的动作&#xff0c;在做前面的动作。 出教室的时候&#xff0c;关灯。 如果是过去时とき那么&#xff0c;是先做前面的动作&#…

Linux安装elk

稍后补充。 目录 01【安装elk】 es单机 es集群 esHead插件 kibana logstash elastic search:https://www.elastic.co/cn/downloads/elasticsearchlogstash:https://www.elastic.co/cn/downloads/logstashkibana:https://www.elastic.co/cn/downloads/kibana linux下安装E…

vector的介绍

vector的介绍&#xff1a;(vector翻译是向量&#xff0c;但是表示的是顺序表) vector是表示可以改变大小的数组的序列容器。 就像数组一样&#xff0c;vector对其元素使用连续的存储位置&#xff0c;这意味着也可以使用指向其元素的常规指针上的偏移量来访问它们的元素&#xf…

前端代码规范配置

前端代码规范配置 涉及到了eslint、prettier、husky、lint-staged等工具包的使用。 代码规则校验 使用eslint定义代码风格 安装eslint并在.eslintrc.js文件中配置。 npm i eslint -D这个代码风格可以使用公司团队内的规范&#xff0c;如果没有可以在github中找到一些主流的…

主机访问不到虚拟机(centos7)web服务的解决办法

目录 一、背景 二、解决办法 2.1、配置虚拟机防火墙 2.2、修改虚拟机网络编辑器 一、背景 主机可以访问外网&#xff0c;虚拟机使用命令&#xff1a;curl http://网址&#xff0c;可以访问到web服务 &#xff0c;主机使用http://网址&#xff0c;访问不到虚拟机&#xff08…

TikTok掀动出海淘金潮

嘉晟迪科&#xff1a;在各行各业都已经卷成红海的今天&#xff0c;最稀缺的是什么&#xff1f;当然是增长。那么&#xff0c;增长在哪里&#xff1f;流量在哪里&#xff0c;需求就在哪里&#xff0c;增长也就在那里。 因为短视频风靡全球的流行&#xff0c;内容平台特别是短视频…

Python-web开发学习笔记(2)--- HTML基础

先回顾一下上一篇文章&#xff1a;Python-web开发学习笔记&#xff08;1&#xff09;--- HTML基础_python web开发笔记_尚拙谨言的博客-CSDN博客 中讲了哪几个常用的HTML标签&#xff1a; <head>&#xff1a;头声明 <title>&#xff1a;网页标题 <h1>~<h6…

QT入门看这一篇就够了——超详细讲解(40000多字详细讲解,涵盖qt大量知识)

目录 一、Qt概述 1.1 什么是Qt 1.2 Qt的发展史 1.3 Qt的优势 1.4 Qt版本 1.5 成功案例 二、创建Qt项目 2.1 使用向导创建 2.2 一个最简单的Qt应用程序 2.2.1 main函数中 2.2.2 类头文件 2.3 .pro文件 2.4 命名规范 2.5 QtCreator常用快捷键 三、Qt按钮小程序 …

深度学习实战四:全连接神经网络(基于Pytorch,含数据和详细注释)

文章目录 概念softmax与交叉熵反向传播计算机视觉工具包torchvision全连接神经网络实现多分类概念 神经网络的第一层为输入层,最后一层为输出层,中间的所有层都叫做隐藏层 在计算神经网络层数时,一般不计算输入层,比如: 该神经网络的层数为2。输入层神经元有3个,隐藏层…

redis缓存数据库的使用

一&#xff0c;什么是redis &#xff1f;为什么要用它&#xff1f; 简单介绍&#xff1a; Redis是开源的key-value缓存框架&#xff0c;由c语言编写&#xff0c;也是一款高性能的框架提供多种语言的API 。 SET 每秒11万次 取get每秒81000次。 数据完全存储在内存空间中&…