在Spring Boot Starter中获取 ArtifactId和版本

2022-09-03 09:20:49

我目前正在开发一个Spring Boot Starter,它将托管一个Restful Web服务,其中包含有关正在运行的应用程序的一些元数据。

我在从我的mainfest文件中提取我的artifactId和versionId时遇到了困难。我相信我的问题是自动配置类在主测试应用程序之前加载,因此清单尚不可用。我不确定我在这里的逻辑是否正确,以及我是否从错误的角度处理问题。

我最初按照以下教程进行设置。

这给了我3个独立的项目

Generic Spring Services with no context AutoConfiguration project for these services Spring Boot starter

我将启动器与测试项目配对作为最终结果。

目前,maven正与Spring Boot一起使用以生成清单文件。

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;
  }

当前清单实现标题:

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


答案 1

经过大量的努力,我找到了一个令人惊讶的简单答案。这就是弹簧-启动-执行器获取信息的方式。

Spring Boot Maven插件配备了构建信息目标。只要这个目标在主项目中触发,Spring就有一个BuildProperties类,你可以连接以获取信息。

            <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

不幸的是,我从来没有完全理解为什么我无法访问正确的清单,但这应该可以帮助其他任何试图解决这个问题的人。


答案 2

另一个答案是完全正确的。只是为了其他人发现这个问题,如果你使用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


推荐