1. 在 Maven 的 pom.xml
中:<profiles>
与 <profileActive>
文件:pom.xml
作用域:项目构建(Build / Package)时
目的:在使用 Maven 打包(mvn package
)或编译时,根据不同的环境激活不同的构建行为(例如:使用不同的配置文件、注入不同的资源、设置不同的最终Jar包名称等)。
典型配置结构:
xml
<project> <profiles> <!-- 定义一个名为 "dev" 的Maven构建profile --> <profile> <id>dev</id> <properties> <!-- 定义一个Maven变量,在构建过程中使用 --> <build.profile>dev</build.profile> </properties> <activation> <!-- 默认激活这个profile --> <activeByDefault>true</activeByDefault> </activation> </profile> <!-- 定义一个名为 "prod" 的Maven构建profile --> <profile> <id>prod</id> <properties> <build.profile>prod</build.profile> </properties> </profile> </profiles> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!-- 资源处理插件:在构建时,用Maven变量替换配置文件中的占位符 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <configuration> <delimiters>@</delimiters> <useDefaultDelimiters>false</useDefaultDelimiters> </configuration> </plugin> </plugins> <resources> <resource> <directory>src/main/resources</directory> <!-- 过滤处理:使${}或@{}占位符被替换 --> <filtering>true</filtering> </resource> </resources> </build> <!-- 在properties中设置profileActive,通常用于指定默认激活的Maven profile --> <properties> <!-- 这个标签本身没有特殊魔法,只是定义一个叫profileActive的变量。 它的值需要被<activation>或命令行 -D 来覆盖才有意义 --> <profiles.active>dev</profiles.active> </properties> </project>
如何激活 Maven Profile?
命令行激活:
mvn clean package -P prod
这里的
-P prod
激活了 Maven 中id
为prod
的 profile。
通过
-D
参数覆盖 properties 的值:mvn clean package -Dprofiles.active=prod
Maven Profile 的最终目的:是生成一个为特定环境定制好的应用程序包(如JAR文件)。例如,打一个生产包的步骤是:mvn clean package -P prod
,这样打出来的JAR包里的配置文件就已经是生产环境的配置了。
2. 在 Spring Boot 的 application.properties
或 application.yml
中
文件:src/main/resources/application.properties
或 application.yml
作用域:应用程序运行(Runtime)时
目的:当 Spring Boot 应用启动后,决定加载哪些应用程序配置(如:数据库连接、服务器端口、日志级别等)。
在 application.properties
中:
properties
spring.profiles.active=@profiles.active@
注意:这里的 @profiles.active@
是一个占位符,它会在 Maven 构建过程中被替换掉。替换它的值就来自于上面 Maven 的 pom.xml
中定义的 <build.profile>
或 <profiles.active>
属性。
最终构建完成后,在打好的 JAR 包的 application.properties
文件里,这一行会变成:
properties
spring.profiles.active=prod // 如果你用 -P prod 打的包
在 application.yml
中:
你也可以直接在里面写,但这样就失去了构建时动态指定的灵活性,通常只用于开发默认值。
yaml
spring: profiles: active: dev
Spring spring.profiles.active
的最终目的:是告诉已经运行起来的JVM,应该使用哪些配置来启动Spring应用。
核心区别总结
特性 | Maven Profile (pom.xml ) |
Spring Profile (application.properties ) |
---|---|---|
作用阶段 | 构建时 (Build Time) | 运行时 (Runtime) |
作用对象 | Maven 构建过程本身 | Spring Boot 应用程序 |
主要目的 | 控制如何生成最终的应用包(JAR/WAR) | 控制应用包运行时的行为 |
激活方式 | -P profileName (如 -P prod ) |
--spring.profiles.active=profileName |
常见用法 | 在构建时将特定环境的配置文件打包进JAR | 在启动时选择加载JAR包中已存在的配置 |
工作流举例:打通两者
一个常见的 DevOps 流程会将两者结合使用:
开发阶段:在
application.properties
中写spring.profiles.active=dev
,方便本地调试。构建生产包:运维人员执行命令:
bash
mvn clean package -P prod -DskipTests
-P prod
激活了 Maven 的prod
profile。Maven 的资源过滤功能会将
application.properties
中的占位符@profiles.active@
替换为prod
。最终生成的
app.jar
文件中的application.properties
内容已经是spring.profiles.active=prod
。
部署运行:运维人员直接运行打好的包:
bash
java -jar app.jar
应用启动,Spring Boot 读取包内的
application.properties
,发现spring.profiles.active=prod
,于是自动加载application-prod.yml
中的所有生产环境配置(如数据库地址、Redis密码等)。
结论:pom.xml
中的 <profile>
是用来做包的,而 application.properties
中的 spring.profiles.active
是用来启动包的。它们在不同的生命周期阶段起作用,但可以通过 Maven 的资源过滤功能巧妙地连接在一起。
<?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 http://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.4.8</version>
</parent>
<groupId>com.abc</groupId>
<artifactId>credit-platform-cloud</artifactId>
<version>3.4.0</version>
<packaging>pom</packaging>
<description>功能描述</description>
<organization>
<name>组织名称</name>
<url>https://www.abc.com</url>
</organization>
<modules>
<module>credit-commons</module>
<module>credit-gateway</module>
<module>credit-auth</module>
<module>credit-admin</module>
<module>credit-module</module>
</modules>
<properties>
<profileActive>dev</profileActive>
<credit.cloud.version>3.4.0</credit.cloud.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring.cloud.version>2020.0.3</spring.cloud.version>
<spring.cloud.alibaba.version>2021.1</spring.cloud.alibaba.version>
<log4j2.version>2.15.0</log4j2.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
<version>3.0.3</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.1.RELEASE</version>
<exclusions>
<exclusion>
<groupId>com.alibaba.cloud</groupId>
<artifactId>nacos-config</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.zhuolang</groupId>
<artifactId>credit-commons-dependencies</artifactId>
<version>${credit.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<profileActive>dev</profileActive>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<profileActive>test</profileActive>
<log-path>/opt</log-path>
</properties>
</profile>
<profile>
<id>pro</id>
<properties>
<profileActive>pro</profileActive>
<log-path>/opt</log-path>
</properties>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<encoding>UTF-8</encoding>
<useDefaultDelimiters>true</useDefaultDelimiters>
<!--不需要转码的文件-->
<nonFilteredFileExtensions>
<nonFilteredFileExtension>xls</nonFilteredFileExtension>
<nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>bootstrap.yml</exclude>
<exclude>bootstrap-*.yml</exclude>
<exclude>application.yml</exclude>
<exclude>application-*.yml</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>bootstrap.yml</include>
<include>bootstrap-${profileActive}.yml</include>
<include>application.yml</include>
<include>application-${profileActive}.yml</include>
</includes>
</resource>
</resources>
</build>
</project>