Как получить номер версии проекта Maven | Заметки об отладке Java

Spring Boot Java
Как получить номер версии проекта Maven | Заметки об отладке Java

Эта статья участвует в "Месяце тем Java - Заметки по отладке Java", подробности см.Ссылка на мероприятие

В последнее время мне нужно получить номер версии проекта в проекте.Самый глупый способ это хардкодить номер версии.Конечно я делал это раньше. Но когда я свободен, у меня есть каприз в проекте Spring Boot.pom.xmlНомер версии определения (т.project.versionvalue) можно ли его получить через API? Так что я использовал время рыбалки, чтобы изучить это скучное дело.

В настоящее время большинство проектов Spring Boot будут упакованы в виде пакетов Jar, поэтому я не буду исследовать, что такое пакеты War и пакеты Ear.

Баночка Секрет

Давайте разархивируем Jar-пакет приложения Spring Boot, чтобы посмотреть, сможем ли мы найти в нем какие-то подсказки. существует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()

Но начните открытие с IDEversion=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.

Фильтрация плагинов ресурсов Maven

Когда Maven создает проект, свойства сборки можно установить с помощью плагина ресурсов, а именно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уже настроен таким образом.

      <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 фактически имеет встроенную автоматическую настройку для получения информации о сборке проекта.ProjectInfoAutoConfiguration, Который содержит bean-компонент условияBuildProperties:

    @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Предоставляется много информации о сборке:

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 Bootspring-boot-maven-pluginВыполните следующую команду для генерации:

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Эффективно, мы можем легко получить соответствующую информацию:

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

Суммировать

Сегодня я представил несколько способов получения информации о версии сборки проекта через API, в чем их польза? В основном используется для мониторинга проектов, аудита релизов, DevOps и других областей, включая настраиваемый баннер Spring Boot. Если ваш проект включает в себя CI/CD, он, скорее всего, затронет и этот аспект. Если вы знаете лучший способ получить его, оставьте сообщение для обсуждения, и я дам вам несколько идей.