本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看 活动链接
最近需要在项目中获取项目的版本号,最笨的方法莫过于硬编码一个版本号,当然之前我也是这么干的。不过闲下来的时候突发奇想Spring Boot项目中
pom.xml
定义的版本号(也就是
project.version
的值)能不能通过API获得呢?于是利用摸鱼的时间研究了这种无聊透顶的东西。
目前大多数Spring Boot项目都会打成Jar包,所以什么War包、Ear包的就先不摸索了。
Jar包的秘密
我们先解压一个Spring Boot应用Jar包看看里面能不能找到一些蛛丝马迹。在
META-INF
文件夹中找到了两个相关的东西,一个是
MANIFEST.MF
:
Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Implementation-Title: spring-boot-version
Implementation-Version: 1.0.23
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
Start-Class: cn.felord.SpringBootVersionApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.4.5
Created-By: Maven Jar Plugin 3.2.0
Main-Class: org.springframework.boot.loader.JarLauncher
复制代码
里面包含了我定义的版本号
1.0.23
,
Implementation-Version
这个值好像通过代码能够获得:
String version = this.getClass().getPackage().getImplementationVersion()
复制代码
但是用IDE启动发现
version=null
,不过用
java -jar
运行时
version = 1.0.23
。可能与IDE运行并不是通过
jar
的方式有关。
另一个是
pom.properties
,Maven项目编译会生成一个
Properties
配置文件:
artifactId=spring-boot-version
groupId=cn.felord
version=1.0.23
复制代码
这岂不是读取
Properties
文件就可以了?
String path = "META-INF/maven/cn.felord/spring-boot-version/pom.properties";
ClassPathResource resource = new ClassPathResource(path);
InputStream inputStream = resource.getInputStream();
try (InputStreamReader reader = new InputStreamReader(inputStream)) {
try (BufferedReader bufferedReader = new BufferedReader(reader)) {
bufferedReader.lines()
.forEach(System.out::println);
}
} catch (Exception ignored) {
}
复制代码
依然只能从jar读取,而且比较麻烦。这两种方式都要依赖jar包,有木有不单纯依赖jar包的呢?
Maven资源插件过滤
Maven在构建项目时可以通过资源插件将构建属性即
pom.xml
中的属性注入到指定的资源文件中,具体操作为:
<build>
...
<resources>
<!-- include main.properties -->
<resource>
<directory>src/main/resources</directory