Spring Boot中读取Maven版本号的完美解决方案
在实际项目开发中,我们经常需要在应用程序中显示项目的版本号、名称等信息。这些信息通常定义在Maven的pom.xml文件中,如何在Spring Boot应用中优雅地读取这些信息呢?本文将介绍一种既适用于开发环境又适用于生产环境的完美解决方案。
问题背景
在Spring Boot应用中,我们希望能够:
- 在application.yaml中读取pom.xml的版本信息
- 开发环境(IDE中运行)和打包后都能正常工作
- 配置简单,维护方便
解决方案概述
使用Maven资源过滤功能,配合自定义分隔符,实现pom.xml属性到application.yaml的自动替换。
详细实现步骤
1. 修改pom.xml配置
首先,在pom.xml的<build>
部分添加资源过滤配置:
<build>
<!-- 资源过滤配置 -->
<resources>
<!-- 1️⃣ 对 application*.yaml 配置文件启用过滤 -->
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering> <!-- 开启 Maven 变量替换,例如 ${profile} -->
<includes>
<include>**/application*.yaml</include> <!-- 只过滤 application.yaml、application-dev.yaml 等文件 -->
</includes>
</resource>
<!-- 2️⃣ 其他资源文件不启用过滤,避免不必要的内容替换 -->
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/application*.yaml</exclude> <!-- 排除已经被过滤的 YAML 配置文件 -->
</excludes>
</resource>
</resources>
<plugins>
<!-- Spring Boot Maven插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- Maven编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<!-- Maven资源插件 - 关键配置 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<delimiters>
<!-- 使用@作为分隔符,避免与Spring的${}冲突 -->
<delimiter>@</delimiter>
</delimiters>
<useDefaultDelimiters>false</useDefaultDelimiters>
</configuration>
</plugin>
</plugins>
</build>
2. 配置application.yaml
在application.yaml中使用占位符引用pom.xml中的属性:
# 应用基本信息
app:
version: @project.version@
name: @project.name@
description: @project.description@
groupId: @project.groupId@
artifactId: @project.artifactId@
# 自定义信息端点
build-timestamp: @maven.build.timestamp@
mybatis-plus.version: "@mybatis-plus.version@"
3. 创建配置属性类
创建一个配置属性类来方便地访问这些值:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String version;
private String name;
private String description;
private String groupId;
private String artifactId;
}
4. 创建信息控制器
创建一个REST控制器来显示版本信息:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class InfoController {
@Value("${app.version}")
private String version;
@Value("${app.name}")
private String appName;
@Autowired
private AppProperties appProperties;
/**
* 获取应用基本信息
*/
@GetMapping("/info")
public Map<String, Object> getAppInfo() {
Map<String, Object> info = new HashMap<>();
info.put("name", appName);
info.put("version", version);
info.put("description", appProperties.getDescription());
info.put("groupId", appProperties.getGroupId());
info.put("artifactId", appProperties.getArtifactId());
info.put("timestamp", System.currentTimeMillis());
return info;
}
}
5. 创建自定义Banner(可选)
在src/main/resources
目录下创建banner.txt
文件:
___ _ _ ___ _ _ _____ _ _
| _ ) | | | | | _ ) | | | | |_ _| | | | |
| _ \ | |_| | | _ \ | |_| | | | | |_| |
|___/ \___/ |___/ \___/ |_| \___/
Blog Version: ${app.version}
Spring Boot: ${spring-boot.version}
MybatisPlus: ${mybatis-plus.version}
Build Time: ${build-timestamp}
工作原理
- 资源过滤:Maven在打包过程中会处理
src/main/resources
目录下的资源文件 - 占位符替换:使用
@property.name@
格式的占位符会被替换为pom.xml中对应的值 - 避免冲突:使用
@
而不是${}
作为分隔符,避免与Spring的属性占位符冲突
验证方法
开发环境验证
- 直接在IDE中运行Spring Boot应用
- 访问
http://localhost:8080/info
- 查看控制台输出的banner信息
生产环境验证
- 打包应用:
mvn clean package
- 查看生成的jar包内容:
jar -tf target/your-app.jar
- 检查BOOT-INF/classes/application.yaml文件中的占位符是否被正确替换
- 运行打包后的应用:
java -jar target/your-app.jar
常见问题解答
Q: 为什么使用@而不是${}作为分隔符?
A: 因为Spring Boot也使用${}作为属性占位符,使用@可以避免冲突。
Q: 开发环境中占位符没有被替换?
A: 确保在IDE中正确配置了Maven支持,或者通过Maven命令运行:mvn spring-boot:run
Q: 多模块项目中如何引用父pom的版本?
A: 使用@project.parent.version@
来引用父项目的版本号。
Q: 除了版本号,还能读取哪些信息?
A: 可以读取pom.xml中的所有Maven属性,如:@project.name@
, @project.description@
, @project.url@
等。
总结
这种方案的优势在于:
- ✅ 简单易用:配置一次,到处使用
- ✅ 环境无关:开发和生产环境都能正常工作
- ✅ 灵活扩展:可以读取pom.xml中的任意属性
- ✅ 无代码侵入:不需要编写额外的工具类
通过这种方式,您可以轻松地在Spring Boot应用中集成Maven的项目信息,实现版本信息的统一管理。