从Gradle自动装配BuildProperties bean - NoSuchBeanDefinitionException

时间:2017-09-27 04:25:49

标签: spring spring-boot gradle autowired

我正在尝试从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构建后,{/ 1}}文件存在于build / resources / main / META-INF / build-info.properties中

在我的build-info.properties我试图自动装配构建属性bean

@RestController

我收到以下错误;

@Autowired
private BuildProperties buildProperties;

我认为当存在build-info.properties时会自动创建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 bean。情况似乎并非如此。

12 个答案:

答案 0 :(得分:7)

我遇到的问题可能有所不同,但是我在这里尝试搜索google解决方案,因此,如果有人遇到相同的问题,我将在此处发布。我的错误消息是:

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”中设置“授权Gradle的IDE构建/运行操作”,然后在从IDE进行构建时获得“ bootBuildInfo”任务即可运行。

答案 1 :(得分:4)

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

请参见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的build目录,例如intellij使用out目录(在我的情况下,build-info.properties文件不存在)
  3. 升级gradle插件,也许您遇到了这个问题https://github.com/spring-projects/spring-boot/issues/12266,如果不想等待补丁发布,可以尝试使用以下技巧

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

希望有帮助。

答案 2 :(得分:4)

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

答案 3 :(得分:4)

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

答案 4 :(得分:3)

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

例子在科特林:

@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。

答案 5 :(得分:1)

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

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

答案 6 :(得分:1)

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

springBoot {
    buildInfo()
}

答案 7 :(得分:0)

上面的配置是正确的,但我仍然不确定问题是什么。

最后,最好的解决方案是切换到Spring-boot-actuator。执行器包含预先配置的休止端点中的所有构建信息。

答案 8 :(得分:0)

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

答案 9 :(得分:0)

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

我通过将其添加到build.gradle中来解决了这个问题:

springBoot {
    buildInfo()
}

答案 10 :(得分:0)

添加到@Mike Emery响应中,找到了等效的Java代码,如下所示:

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

答案 11 :(得分:0)

转到File -> Settings

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

enter image description here