Эта статья участвует в "Месяце тем Java - Заметки по отладке Java", подробности см.Ссылка на мероприятие
В последнее время мне нужно получить номер версии проекта в проекте.Самый глупый способ это хардкодить номер версии.Конечно я делал это раньше. Но когда я свободен, у меня есть каприз в проекте Spring Boot.pom.xml
Номер версии определения (т.project.version
value) можно ли его получить через 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, он, скорее всего, затронет и этот аспект. Если вы знаете лучший способ получить его, оставьте сообщение для обсуждения, и я дам вам несколько идей.