从 Gradle 自动装配 BuildProperties bean - NoSuchBeanDefinitionException

Autowiring BuildProperties bean from Gradle - NoSuchBeanDefinitionException

我正在尝试从 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 存在时自动创建。好像不是这样。

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

您的假设是正确的,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)
    

希望对您有所帮助。

我遇到的问题可能有所不同,但我来到这里是为了 google 解决方案,所以我会 post 在这里以防其他人 运行 遇到这个问题同样的问题。我的错误信息是:

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 特有的)

我只需要在 "Build, Execution, Deployment->Build Tools->Gradle" 中设置 "Delegate IDE build/run actions to gradle",然后在从 IDE 构建时将 "bootBuildInfo" 任务转移到 运行。

您需要配置 Intelij 以使用 Gradle Runner,以便它在输出文件夹中生成 build.properties 文件。在设置(首选项)中启用 Delegate IDE build/run 操作到 Gradle 选项 |构建、执行、部署 |构建工具 | Gradle |亚军选项卡。

对于 Maven 项目,在 IntelliJ "Preferences..." 中,在构建、执行、部署 > 构建工具 > Maven > Runner 下,select 选项 "Delegate IDE build/run actions to Maven."

我知道这个问题很老了,但我今天 运行 研究了这个问题并想分享一个替代解决方案。我是来自 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。

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

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

springBoot {
    buildInfo()
}

最新版本的 Intellij 不再有路径“Build, Execution, Deployment->Build Tools->Gradle->Runner”。

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

添加到@Mike Emery 回复中,找到等效的 Java 代码如下:

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

转到File -> Settings

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

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

springBoot {
    buildInfo()
}