【问题标题】:Autowiring BuildProperties bean from Gradle - NoSuchBeanDefinitionException从 Gradle 自动装配 BuildProperties bean - NoSuchBeanDefinitionException
【发布时间】:2018-03-08 10:44:43
【问题描述】:

我正在尝试从 Gradle 构建文件中获取我的 Java 应用程序中的版本。我正在按照这里的说明进行操作;

https://docs.spring.io/spring-boot/docs/current/reference/html/howto-build.html

build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-
        plugin:1.5.7.RELEASE")
    }
}

project.version = '0.1.0'

apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'

springBoot  {
    buildInfo()
}

jar {
    baseName = 'ci-backend'
}

war {
   baseName = 'ci-backend'
}

repositories {
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework:spring-jdbc")
    compile("joda-time:joda-time")

    compile("com.opencsv:opencsv:3.9")
    compile("org.springframework.batch:spring-batch-core")

    testCompile('org.springframework.boot:spring-boot-starter-test')
    providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
 }

使用 gradle 构建后,build-info.properties 文件存在于 build/resources/main/META-INF/build-info.properties 中

在我的@RestController 中,我正在尝试自动装配构建属性 bean

@Autowired
private BuildProperties buildProperties;

我收到以下错误;

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.info.BuildProperties' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 41 more

我假设BuildProperties bean 是在 build-info.properties 存在时自动创建的。好像不是这样的。

【问题讨论】:

  • @Autowired 私有 BuildProperties buildProperties;正在工作和实例化,如果“build-info”文件是由依赖管理框架生成的。

标签: spring spring-boot gradle autowired


【解决方案1】:

我遇到的问题可能有所不同,但我来到这里试图用谷歌搜索解决方案,所以我会在这里发布,以防其他人遇到同样的问题。我的错误信息是:

Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.info.BuildProperties' available

仅当尝试在 IntelliJ 中运行时,而不是从命令行使用 gradle 运行时。 (这可能是 SpringBoot 特有的)

我只需要从“构建、执行、部署->构建工具-> Gradle”中设置“将 IDE 构建/运行操作委托给 gradle”,然后在从 IDE 构建时运行“bootBuildInfo”任务。

【讨论】:

  • 不幸的是,我无法再访问出现此问题的存储库,因此我无法确认原始问题是什么。然而,这里有一些答案肯定会帮助人们面临同样的问题。
【解决方案2】:

对于 Maven 项目,在 IntelliJ“首选项...”中,在构建、执行、部署 > 构建工具 > Maven > Runner 下,选择“将 IDE 构建/运行操作委托给 Maven”选项。

【讨论】:

    【解决方案3】:

    您的假设是正确的,BuildProperties bean 会在 META-INF/build-info.properties 存在时自动创建

    请参阅ProjectInfoAutoConfiguration 中的以下自动配置代码

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

    但是,如果 bean 在您的应用程序上下文中仍然不可用,请尝试以下任一方法:

    1. 确保buildInfo gradle 任务配置正确,运行gradlew bootBuildInfo --debug 并验证结果
    2. 检查您的 IDE 输出目录是否与 gradle 的构建目录不同,例如 intellij 使用 out 目录(在我的情况下,build-info.properties 文件不存在)
    3. 升级你的 gradle 插件,也许你遇到了这个问题https://github.com/spring-projects/spring-boot/issues/12266,如果你不想等待补丁发布,你可以尝试使用以下 hack

      def removeBootBuildInfoWorkaround12266 = task(type: Delete, 'removeBootBuildInfoWorkaround12266') {
          delete new File(buildDir, 'resources/main/META-INF/build-info.properties')
      }
      tasks.find { it.name == 'bootBuildInfo' }.dependsOn(removeBootBuildInfoWorkaround12266)
      

    希望对你有帮助。

    【讨论】:

    • 不幸的是,我无法再访问出现此问题的存储库,因此我无法确认原始问题是什么。然而,这里有一些答案肯定会帮助人们面临同样的问题。
    • 这个答案结束了我半天的搜索非常感谢!
    【解决方案4】:

    您需要将 Intelij 配置为使用 Gradle Runner,以便它在 out 文件夹中生成 build.properties 文件。在设置(首选项)中启用 将 IDE 构建/运行操作委托给 Gradle 选项 |构建、执行、部署 |构建工具 |摇篮 |跑步者选项卡。

    【讨论】:

      【解决方案5】:

      我知道这个问题很老,但我今天遇到了它,想分享一个替代解决方案。我正在运行来自独立包中的 IntelliJ 的测试(尽管您可以添加注释以限制加载此配置,然后它可以只存在于主包中)

      示例在 kotlin 中:

      @Configuration
      class IntegrationAppConfig {
          @Bean
          @ConditionalOnMissingBean(BuildProperties::class)
          fun buildProperties(): BuildProperties = BuildProperties(Properties()).also {
              logger.error("BuildProperties bean did not auto-load, creating mock BuildProperties")
          }
      }
      

      这使您可以根据需要继续使用 IntelliJ 运行,而无需通过 Gradle。

      【讨论】:

        【解决方案6】:

        最新版本的 Intellij 不再具有“构建、执行、部署->构建工具->Gradle->Runner”路径。

        要获得相同的结果,请转到“构建、执行、部署->构建工具->Gradle->Gradle 项目”并在“构建并运行使用:”中选择 Gradle。

        【讨论】:

          【解决方案7】:

          要添加到@Mike Emery 响应中,请在下面找到等效的 Java 代码:

          @Bean @ConditionalOnMissingBean(BuildProperties.class)
          BuildProperties buildProperties() {
              log.error("BuildProperties bean did not auto-load, creating it");
              return new BuildProperties(new Properties());
          }
          

          【讨论】:

            【解决方案8】:

            转到File -> Settings

            然后转到选项"Build, Execution, Deployment"->Build Tools->Gradle->Runner

            【讨论】:

              【解决方案9】:

              我也遇到了同样的问题,这是 maven 问题,我升级了我的 maven 版本(3.3.9)并内置了命令提示符,而不是在 IDE 中构建它。我知道这很奇怪,但是是的,这对我有用。

              【讨论】:

              • 这是因为,与@Casper 所说的类似,build-info.properties 不是由 IntelliJ 构建的。当您 mvn clean 项目时,它会被删除。如果有人知道如何让 IntelliJ 构建它,将不胜感激。
              • 在 Intellij 中,编辑运行配置时,我可以添加 spring-boot:build-info 的启动前 Maven 目标。必须对所有配置进行处理有点痛苦,我怀疑@izilotti 解决方案将是一次性的
              【解决方案10】:

              build.gradle 中添加以下内容为我解决了这个问题:

              springBoot {
                  buildInfo()
              }
              

              【讨论】:

              • 这些行已包含在问题的build.gradle
              【解决方案11】:

              这一步作者已经完成了,但我发现自己和作者一样的错误,没有任何帮助。但这有所帮助:

              我通过将它添加到 build.gradle 来解决它:

              springBoot {
                  buildInfo()
              }
              

              【讨论】:

              • 如前所述:作者在他的构建文件中已经有了这个,但也许我的回答会帮助一些人寻找这个问题的答案
              猜你喜欢
              • 2017-03-02
              • 2016-01-07
              • 1970-01-01
              • 1970-01-01
              • 2011-01-23
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多