<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何在代碼中獲取Java應(yīng)用當(dāng)前的版本號?

          共 8815字,需瀏覽 18分鐘

           ·

          2021-06-08 05:00

          最近需要在項(xiàng)目中獲取項(xiàng)目的版本號,最笨的方法莫過于硬編碼一個(gè)版本號,當(dāng)然我也是這么干的。不過閑下來的時(shí)候突發(fā)奇想Spring Boot項(xiàng)目中pom.xml定義的版本號能不能通過API獲得呢?于是利用摸魚的時(shí)間研究了這種無聊透頂?shù)臇|西。

          ?

          目前大多數(shù)Spring Boot項(xiàng)目都會(huì)打成Jar包,所以什么War包、Ear包的就先不摸索了。

          Jar包的秘密

          我們先解壓一個(gè)Spring Boot應(yīng)用Jar包看看里面能不能找到一些蛛絲馬跡。在META-INF文件夾中找到了兩個(gè)相關(guān)的東西,一個(gè)是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.23Implementation-Version這個(gè)值好像通過代碼能夠獲得:

          String version = this.getClass().getPackage().getImplementationVersion()

          但是用IDE啟動(dòng)發(fā)現(xiàn)version=null,不過用java -jar運(yùn)行時(shí)version = 1.0.23。可能與IDE運(yùn)行并不是通過jar的方式有關(guān)。

          另一個(gè)是pom.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在構(gòu)建項(xiàng)目時(shí)可以通過資源插件將構(gòu)建屬性即pom.xml中的屬性注入到指定的資源文件中,具體操作為:

          <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中已經(jīng)設(shè)置了這種方式。

                <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,你可以通過下面的方式來接收版本號:

          application.version = ${project.version}

          如果是application.yaml,你可以通過下面的方式來接收版本號:

          application:
            version: '@project.version@'

          然后如何取值就不用多說了吧。這種方式不依賴jar包,使用起來也很簡單。

          Spring Boot提供

          Spring Boot其實(shí)已經(jīng)內(nèi)置了獲取項(xiàng)目構(gòu)建信息的自動(dòng)配置ProjectInfoAutoConfiguration,它包含一個(gè)條件BeanBuildProperties

              @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()));
              }

          這個(gè)BuildProperties提供了不少構(gòu)建信息:

          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執(zhí)行下面的命令生成:

          mvn spring-boot:build-info

          我們只需要配置插件為:

          <plugin>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-maven-plugin</artifactId>
              <executions>
                  <execution>
                      <goals>
                          <goal>
                              build-info
                          </goal>
                      </goals>
                  </execution>
              </executions>
          </plugin>

          就能使得BuildProperties生效,我們可以輕松取得相關(guān)的信息:

          {
            "version" : "1.0.23",
            "group" : "cn.felord",
            "artifact" : "spring-boot-version",
            "name" : "spring-boot-version",
            "time" : {
              "epochSecond" : 1620664643,
              "nano" : 591000000
            }
          }

          總結(jié)

          今天介紹了幾種從通過API獲取項(xiàng)目構(gòu)建版本信息的方法,有什么用呢?主要用于項(xiàng)目監(jiān)控,發(fā)版審計(jì),DevOps等領(lǐng)域,包括Spring Boot的自定義banner也可以使用。算是一個(gè)錦上添花的小Tips,簡單了解一下就好。

          往期推薦

          微信繼續(xù)加持上班摸魚功能!網(wǎng)友:離被開除更進(jìn)一步...

          共同創(chuàng)造最好的OS,openEuler Developer Day 報(bào)名通道開啟

          字節(jié)又莫名其妙發(fā)獎(jiǎng)金了!網(wǎng)友:突然到賬五萬,嚇得我差點(diǎn)報(bào)警...

          線上SQL腳本執(zhí)行錯(cuò)了出事之后互相甩鍋怎么辦?

          三孩政策來了!網(wǎng)友:65歲沒死,要帶9個(gè)孫兒;限購兩套房怎么分?


          推薦關(guān)注本文作者:碼農(nóng)小胖哥

          分享高質(zhì)量編程知識(shí),探討IT人生

          技術(shù)干貨,實(shí)戰(zhàn)技巧,面試技巧,前沿資訊一個(gè)都不能少

          瀏覽 63
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  操校花视频 | 天天插,天天狠,天天透 | 欧美成人精品一二三区欧美风情 | 波多野结衣一区二区三区在线观看 | 91性爱在线观看 |