在 Spring Boot Starter 中获取 ArtifactId 和版本
Getting ArtifactId and Version in Spring Boot Starter
我目前正在开发 Spring Boot Starter,它将托管 Restful Web 服务,其中包含一些 meta-data 关于 运行 应用程序。
我在从我的 mainfest 文件中提取我的 artifactId 和 versionId 时遇到困难。我相信我的问题是自动配置 类 在主测试应用程序之前加载,因此清单尚无法被发现。我不确定我的逻辑是否正确,是否从错误的角度处理问题。
我最初是按照以下tutorial进行设置的。
这给了我 3 个独立的项目
Generic Spring Services with no context
AutoConfiguration project for these services
Spring Boot starter
我将启动器与测试项目配对作为最终结果。
当前 Maven 与 Spring 引导一起使用以生成清单文件。
Implementation-Title: MyExampleProjectWithCustomStarter
Implementation-Version: 0.0.1-SNAPSHOT
Archiver-Version: Plexus Archiver
Built-By: mcf
Implementation-Vendor-Id: com.coolCompany
Spring-Boot-Version: 1.5.4.RELEASE
Implementation-Vendor: Pivotal Software, Inc.
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.coolcompany.SpringBootExampleApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Created-By: Apache Maven 3.5.0
Build-Jdk: 1.8.0_131
Implementation-URL: http://someurl
但是,当我尝试从我的通用服务包中找到示例项目的清单文件时,我找不到该文件。
private String getApplicationVersion(String applicationName, List<Attributes> manifests) {
String unknownVersion = "0.0.0-UNKNOWN";
for (Attributes attr : manifests) {
String title = attr.getValue(IMPL_TITLE);
String version = attr.getValue(IMPL_VERSION);
if (version != null) {
if (applicationName.equalsIgnoreCase(title)) {
return title + ' ' + version;
}
}
}
log.warn(
"Could not find MANIFEST file with '" + applicationName + "' as Implementation-Title."
+ " Meta-API will return buildVersion '" + unknownVersion + "'.");
return applicationName + ' ' + unknownVersion;
}
private List<Attributes> loadManifestFiles() {
List<Attributes> manifests = new ArrayList<>();
try {
Enumeration<URL> resources =
Thread.currentThread().getContextClassLoader().getResources("/META-INF/MANIFEST.MF");
while (resources.hasMoreElements()) {
URL url = resources.nextElement();
try (InputStream is = url.openStream()) {
manifests.add(new Manifest(is).getMainAttributes());
System.out.println("Manifest size:" + manifests.size());
} catch (IOException e) {
log.error("Failed to read manifest from " + url, e);
}
}
} catch (IOException e) {
log.error("Failed to get manifest resources", e);
}
return manifests;
}
当前清单Implementation-Titles:
Spring Boot Web Starter
Spring Boot Starter
Spring Boot
Spring Boot AutoConfigure
Spring Boot Logging Starter
null
null
jcl-over-slf4j
null
log4j-over-slf4j
null
Spring Boot Tomcat Starter
Apache Tomcat
Apache Tomcat
Apache Tomcat
hibernate-validator
null
JBoss Logging 3
ClassMate
jackson-databind
Jackson-annotations
Jackson-core
spring-web
spring-aop
spring-beans
spring-context
spring-webmvc
spring-expression
Spring Boot Actuator Starter
Spring Boot Actuator
null
** MyCustom-spring-boot-starter
** MyGenericSpringService
null
null
null
Metrics Core
JVM Integration for Metrics
null
null
Jackson datatype: JSR310
** MyService-spring-boot-autoconfigure
slf4j-api
spring-core
** 缺少 MyExampleProjectWithCustomStarter
清单记录数:44
经过一番努力,我找到了一个出奇简单的答案。 spring-boot-actuator 是这样获取信息的。
Spring Boot Maven 插件配备了构建信息目标。只要在主项目中触发此目标 Spring 就有一个 BuildProperties class,您就可以输入信息。
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>build-info</id>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
您可以像这样访问启动器中的属性:
@Autowired
BuildProperties buildProperties;
...
buildProperties.getArtifact();
buildProperties.getVersion();
您甚至可以从插件中指定其他属性。有关详细信息,请参阅插件文档:
https://docs.spring.io/spring-boot/docs/current/maven-plugin/build-info-mojo.html
不幸的是,我从来没有完全理解为什么我无法访问正确的清单,但这应该可以帮助其他任何试图解决这个问题的人。
另一个答案完全正确。仅供其他人在使用 Gradle 而不是 Maven 时发现此问题:
生成构建信息就像将其添加到您的 build.gradle
文件一样简单:
plugins {
id 'org.springframework.boot' version '<your-boot-version>.RELEASE'
}
// ...
springBoot {
buildInfo()
}
如果您想传递自定义属性:
springBoot {
buildInfo {
properties {
additional = [
'property.name': 'property value',
'other.property': 'different.value'
]
}
}
}
然后Java代码中的用法与使用BuildProperties
相同。您可以在 this guide.
中找到有关该插件的更多信息
我目前正在开发 Spring Boot Starter,它将托管 Restful Web 服务,其中包含一些 meta-data 关于 运行 应用程序。
我在从我的 mainfest 文件中提取我的 artifactId 和 versionId 时遇到困难。我相信我的问题是自动配置 类 在主测试应用程序之前加载,因此清单尚无法被发现。我不确定我的逻辑是否正确,是否从错误的角度处理问题。
我最初是按照以下tutorial进行设置的。
这给了我 3 个独立的项目
Generic Spring Services with no context
AutoConfiguration project for these services
Spring Boot starter
我将启动器与测试项目配对作为最终结果。
当前 Maven 与 Spring 引导一起使用以生成清单文件。
Implementation-Title: MyExampleProjectWithCustomStarter
Implementation-Version: 0.0.1-SNAPSHOT
Archiver-Version: Plexus Archiver
Built-By: mcf
Implementation-Vendor-Id: com.coolCompany
Spring-Boot-Version: 1.5.4.RELEASE
Implementation-Vendor: Pivotal Software, Inc.
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.coolcompany.SpringBootExampleApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Created-By: Apache Maven 3.5.0
Build-Jdk: 1.8.0_131
Implementation-URL: http://someurl
但是,当我尝试从我的通用服务包中找到示例项目的清单文件时,我找不到该文件。
private String getApplicationVersion(String applicationName, List<Attributes> manifests) {
String unknownVersion = "0.0.0-UNKNOWN";
for (Attributes attr : manifests) {
String title = attr.getValue(IMPL_TITLE);
String version = attr.getValue(IMPL_VERSION);
if (version != null) {
if (applicationName.equalsIgnoreCase(title)) {
return title + ' ' + version;
}
}
}
log.warn(
"Could not find MANIFEST file with '" + applicationName + "' as Implementation-Title."
+ " Meta-API will return buildVersion '" + unknownVersion + "'.");
return applicationName + ' ' + unknownVersion;
}
private List<Attributes> loadManifestFiles() {
List<Attributes> manifests = new ArrayList<>();
try {
Enumeration<URL> resources =
Thread.currentThread().getContextClassLoader().getResources("/META-INF/MANIFEST.MF");
while (resources.hasMoreElements()) {
URL url = resources.nextElement();
try (InputStream is = url.openStream()) {
manifests.add(new Manifest(is).getMainAttributes());
System.out.println("Manifest size:" + manifests.size());
} catch (IOException e) {
log.error("Failed to read manifest from " + url, e);
}
}
} catch (IOException e) {
log.error("Failed to get manifest resources", e);
}
return manifests;
}
当前清单Implementation-Titles:
Spring Boot Web Starter
Spring Boot Starter
Spring Boot
Spring Boot AutoConfigure
Spring Boot Logging Starter
null
null
jcl-over-slf4j
null
log4j-over-slf4j
null
Spring Boot Tomcat Starter
Apache Tomcat
Apache Tomcat
Apache Tomcat
hibernate-validator
null
JBoss Logging 3
ClassMate
jackson-databind
Jackson-annotations
Jackson-core
spring-web
spring-aop
spring-beans
spring-context
spring-webmvc
spring-expression
Spring Boot Actuator Starter
Spring Boot Actuator
null
** MyCustom-spring-boot-starter
** MyGenericSpringService
null
null
null
Metrics Core
JVM Integration for Metrics
null
null
Jackson datatype: JSR310
** MyService-spring-boot-autoconfigure
slf4j-api
spring-core
** 缺少 MyExampleProjectWithCustomStarter
清单记录数:44
经过一番努力,我找到了一个出奇简单的答案。 spring-boot-actuator 是这样获取信息的。
Spring Boot Maven 插件配备了构建信息目标。只要在主项目中触发此目标 Spring 就有一个 BuildProperties class,您就可以输入信息。
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>build-info</id>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
您可以像这样访问启动器中的属性:
@Autowired
BuildProperties buildProperties;
...
buildProperties.getArtifact();
buildProperties.getVersion();
您甚至可以从插件中指定其他属性。有关详细信息,请参阅插件文档: https://docs.spring.io/spring-boot/docs/current/maven-plugin/build-info-mojo.html
不幸的是,我从来没有完全理解为什么我无法访问正确的清单,但这应该可以帮助其他任何试图解决这个问题的人。
另一个答案完全正确。仅供其他人在使用 Gradle 而不是 Maven 时发现此问题:
生成构建信息就像将其添加到您的 build.gradle
文件一样简单:
plugins {
id 'org.springframework.boot' version '<your-boot-version>.RELEASE'
}
// ...
springBoot {
buildInfo()
}
如果您想传递自定义属性:
springBoot {
buildInfo {
properties {
additional = [
'property.name': 'property value',
'other.property': 'different.value'
]
}
}
}
然后Java代码中的用法与使用BuildProperties
相同。您可以在 this guide.