Spring   发布时间:2022-04-09  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了java – 使用@ConditionalOnBean的Spring Boot传递@Component依赖项大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

我有一个Spring Boot 1.5.x项目,其中一些@Component依赖于其他@Component,并且最终沿着依赖链,可以使用@ConditionalOnProperty完全启用或禁用某些@Component.

我正在使用@ConditionalOnBean来避免实例化依赖于因缺少属性而未实例化的其他@Component的@Component.

但是,它只适用于直接依赖,而不适用于传递依赖,但我无法理解为什么.

我试着用一个简单的例子来解释.

虑Myservices.kt:

private val logger = KotlinLogging.logger {}

class Myservices

@ConditionalOnProperty("service.a")
@service
class serviceA {
    init {
        logger.info { "A serviCE" }
    }
}

@ConditionalOnBean(serviceA::class)
@ConditionalOnProperty("service.b")
@service
class serviceB(
        private val serviceA: serviceA
) {
    init {
        logger.info { "B serviCE depends on $serviceA" }
    }
}

@ConditionalOnBean(serviceB::class)
@ConditionalOnProperty("service.c")
@service
class serviceC(
        private val serviceB: serviceB
) {
    init {
        logger.info { "C service depends on $serviceB" }
    }
}

使用以下application.yml:

service:
  a: false
  b: true
  c: true

然后Spring在启动时崩溃,具体如下:

**************************
APPLICATION Failed TO START
***************************

Description:

Parameter 0 of constructor in org.gotson.transitivebeandependencies.serviceC required a bean of type 'org.gotson.transitivebeandependencies.serviceB' that Could not be found.


Action:

Consider defining a bean of type 'org.gotson.transitivebeandependencies.serviceB' in your configuration.

以下是自动配置的结果:

Positive matches:

serviceC matched:
      - @ConditionalOnProperty (service.C) matched (OnPropertyCondition)
      - @ConditionalOnBean (types: org.gotson.transitivebeandependencies.serviceB; SearchStrategy: all) found bean 'serviceB' (OnBeanCondition)

Negative matches:

serviceA:
      Did not match:
         - @ConditionalOnProperty (service.a) found different value in property 'service.a' (OnPropertyCondition)

   serviceB:
      Did not match:
         - @ConditionalOnBean (types: org.gotson.transitivebeandependencies.serviceA; SearchStrategy: all) did not find any beans (OnBeanCondition)
      Matched:
         - @ConditionalOnProperty (service.b) matched (OnPropertyCondition)

但是,使用以下application.yml:

service:
  a: true
  b: false
  c: true

然后一切正常,只有一个serviceA实例被实例化,而没有创建serviceB和serviceC bean.

与@Bean而不是@Component相同的行为按预期工作.

@H_570_1@myBeans.kt:

private val logger = KotlinLogging.logger {}

@Configuration
class MyBeans {

    @ConditionalOnProperty("bean.a")
    @Bean
    fun beanA(): BeanA {
        logger.info { "A BEAN" }
        return BeanA("beanA")
    }

    @ConditionalOnBean(BeanA::class)
    @ConditionalOnProperty("bean.b")
    @Bean
    fun beanB(beanA: BeanA): BeanB {
        logger.info { "B BEAN depends on $beanA" }
        return BeanB("beanB")
    }

    @ConditionalOnBean(BeanB::class)
    @ConditionalOnProperty("bean.c")
    @Bean
    fun beanC(beanB: BeanB): BeanC {
        logger.info { "C BEAN depends on $beanB" }
        return BeanC("beanC")
    }

}

data class BeanA(val name: String)
data class BeanB(val name: String)
data class BeanC(val name: String)

使用application.yml:

bean:
  a: false
  b: true
  c: true

我没有实例化BeanA,BeanB或BeanC类型的bean.

以下是自动配置的结果:

Negative matches:

MyBeans#beanA:
      Did not match:
         - @ConditionalOnProperty (bean.a) found different value in property 'bean.a' (OnPropertyCondition)

   MyBeans#beanB:
      Did not match:
         - @ConditionalOnBean (types: org.gotson.transitivebeandependencies.beanA; SearchStrategy: all) did not find any beans (OnBeanCondition)
      Matched:
         - @ConditionalOnProperty (bean.b) matched (OnPropertyCondition)

   MyBeans#beanC:
      Did not match:
         - @ConditionalOnBean (types: org.gotson.transitivebeandependencies.beanB; SearchStrategy: all) did not find any beans (OnBeanCondition)
      Matched:
         - @ConditionalOnProperty (bean.C) matched (OnPropertyCondition)

我已经设置了一个带有测试的样本repo来重现:https://github.com/gotson/spring-transitive

最佳答案
@ConditionalOnBean是一个bean注册阶段检查,因此需要概述ApplicationContext中有效的bean.可以使用常规@Bean以标准方式注册Bean,从而暴露与方法的返回类型相同的目标类型.您可能还有一个更复杂的逻辑factorybean,可以导致我们必须处理的异国情调设置.

无论如何,订购是关键.如果希望bean类型匹配正常工作,则必须按给定顺序处理配置类.如果你有一个C1配置类,只有当bean B可用并且所述bean由C2提供时才提供bean A,C2必须先运行.

Spring Boot有两个解析阶段:首先我们解析所有用户的配置.完成后,我们解析自动配置的bean定义.自动配置本身是有序的(使用@AutoConfigureBefore,@ AutoConfigureAfter).这样,我们可以保证,如果您将@ConditionalOnBean置于自动配置中,它将按照预期处理用户配置.如果您依赖其他自动配置所贡献的内容,您可以使用这些注释轻松订购.

您的设置完全避免订购,因此如果订购是正确的,它可以工作,如果不是,则不工作. @ConditionalOnBean的Javadoc显然是states that

如果您想了解更多信息,可以参加3小时的大学课程,即这个主题on youtube.

大佬总结

以上是大佬教程为你收集整理的java – 使用@ConditionalOnBean的Spring Boot传递@Component依赖项全部内容,希望文章能够帮你解决java – 使用@ConditionalOnBean的Spring Boot传递@Component依赖项所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。