簡體   English   中英

是否可以使用 Spring(無彈簧啟動)創建與 @ConditionalOnMissingBean 等效的自定義條件?

[英]Is it possible to create a custom condition equivalate of @ConditionalOnMissingBean with Spring (no spring-boot)?

我正在嘗試實現一個 Spring 條件,僅當某個 class 沒有其他 bean 時才會加載我的 bean。 所需的行為類似於“@ConditionalOnMissingBean”,但不使用 spring-boot。

我正在使用 Spring 版本 5.3.13。

那可能嗎? 謝謝。

我通過挖掘 spring-boot 源代碼找到了解決方案。 ConditionalOnBean 僅適用於配置中定義的 bean(bean 方法)。 spring-boot java 文檔也推薦了 @ConditionalOnBean

該條件只能匹配到目前為止已由應用程序上下文處理的 bean 定義,因此,強烈建議僅在自動配置類上使用此條件。 如果候選 bean 可能由另一個自動配置創建,請確保使用此條件的 bean 在之后運行。

這是我提出的解決方案的基礎知識,這可能會有所改進,但基礎知識運行良好。

條件:

@Slf4j
class MissingBeanCondition implements ConfigurationCondition {
    @Override
    public ConfigurationPhase getConfigurationPhase() {
        return ConfigurationPhase.REGISTER_BEAN;
    }

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        var targetBeanType = metadata.getAnnotations()
                .get(ConditionalOnMissingBean.class)
                .getValue("value", Class.class)
                // TODO throw a more informative error
                .orElseThrow(() -> new RuntimeException("Failed to evaluate MissingBeanCondition"));
        
        try {
            context.getBeanFactory().getBean(targetBeanType);
        } catch (NoSuchBeanDefinitionException e) {
            return true;
        }
       
        return false;
    }
}

注釋:

@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Conditional(MissingBeanCondition.class)
public @interface ConditionalOnMissingBean {
    Class<?> value();
}

使用示例:

@Bean
@Singleton
@ConditionalOnMissingBean(Provider.class)
public Provider myClass() {
    return new DefaultProvider();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM