前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何在代码中获取Java应用当前的版本号?

如何在代码中获取Java应用当前的版本号?

作者头像
码农小胖哥
发布2021-05-14 10:47:25
5.6K0
发布2021-05-14 10:47:25
举报
最近需要在项目中获取项目的版本号,最笨的方法莫过于硬编码一个版本号,当然我也是这么干的。不过闲下来的时候突发奇想Spring Boot项目中pom.xml定义的版本号能不能通过API获得呢?于是利用摸鱼的时间研究了这种无聊透顶的东西。

❝目前大多数Spring Boot项目都会打成Jar包,所以什么War包、Ear包的就先不摸索了。

Jar包的秘密

我们先解压一个Spring Boot应用Jar包看看里面能不能找到一些蛛丝马迹。在META-INF文件夹中找到了两个相关的东西,一个是MANIFEST.MF

代码语言:javascript
复制
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.23Implementation-Version这个值好像通过代码能够获得:

代码语言:javascript
复制
String version = this.getClass().getPackage().getImplementationVersion()

但是用IDE启动发现version=null,不过用java -jar运行时version = 1.0.23。可能与IDE运行并不是通过jar的方式有关。

另一个是pom.properties:

代码语言:javascript
复制
artifactId=spring-boot-version
groupId=cn.felord
version=1.0.23

这岂不是读取Properties文件就可以了?

代码语言:javascript
复制
  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在构建项目时可以通过资源插件将构建属性即pom.xml中的属性注入到指定的资源文件中,具体操作为:

代码语言:javascript
复制
<build>
  ...
  <resources>
    <!-- include main.properties -->
    <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
      <includes>
        <include>main.properties</include>
      </includes>
    </resource>
  </resources>
  ...
</build>

恰好spring-boot-starter-parent中已经设置了这种方式。

代码语言:javascript
复制
      <resource>
        <directory>${basedir}/src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
          <include>**/application*.yml</include>
          <include>**/application*.yaml</include>
          <include>**/application*.properties</include>
        </includes>
      </resource>

如果你是application.properties,你可以通过下面的方式来接收版本号:

代码语言:javascript
复制
application.version = ${project.version}

如果是application.yaml,你可以通过下面的方式来接收版本号:

代码语言:javascript
复制
application:
  version: '@project.version@'

然后如何取值就不用多说了吧。这种方式不依赖jar包,使用起来也很简单。

Spring Boot提供

Spring Boot其实已经内置了获取项目构建信息的自动配置ProjectInfoAutoConfiguration,它包含一个条件BeanBuildProperties

代码语言:javascript
复制
    @ConditionalOnResource(
        resources = {"${spring.info.build.location:classpath:META-INF/build-info.properties}"}
    )
    @ConditionalOnMissingBean
    @Bean
    public BuildProperties buildProperties() throws Exception {
        return new BuildProperties(this.loadFrom(this.properties
                                                 .getBuild()
                                                 .getLocation(), "build",                                                     this.properties
                                                 .getBuild().getEncoding()));
    }

这个BuildProperties提供了不少构建信息:

代码语言:javascript
复制
public class BuildProperties extends InfoProperties {
    public BuildProperties(Properties entries) {
        super(processEntries(entries));
    }

    public String getGroup() {
        return this.get("group");
    }

    public String getArtifact() {
        return this.get("artifact");
    }

    public String getName() {
        return this.get("name");
    }

    public String getVersion() {
        return this.get("version");
    }

    public Instant getTime() {
        return this.getInstant("time");
    }
   } 

其中的条件build-info.properties可以通过Spring Boot插件spring-boot-maven-plugin执行下面的命令生成:

代码语言:javascript
复制
mvn spring-boot:build-info

我们只需要配置插件为:

代码语言:javascript
复制
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>
                    build-info
                </goal>
            </goals>
        </execution>
    </executions>
</plugin>

就能使得BuildProperties生效,我们可以轻松取得相关的信息:

代码语言:javascript
复制
{
  "version" : "1.0.23",
  "group" : "cn.felord",
  "artifact" : "spring-boot-version",
  "name" : "spring-boot-version",
  "time" : {
    "epochSecond" : 1620664643,
    "nano" : 591000000
  }
}

总结

今天介绍了几种从通过API获取项目构建版本信息的方法,有什么用呢?主要用于项目监控,发版审计,DevOps等领域,包括Spring Boot的自定义banner也可以使用。算是一个锦上添花的小Tips,简单了解一下就好。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-05-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农小胖哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Jar包的秘密
  • 从配置文件读取
  • Spring Boot提供
  • 总结
相关产品与服务
CODING DevOps
CODING DevOps 一站式研发管理平台,包括代码托管、项目管理、测试管理、持续集成、制品库等多款产品和服务,涵盖软件开发从构想到交付的一切所需,使研发团队在云端高效协同,实践敏捷开发与 DevOps,提升软件交付质量与速度。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档