web-dev-qa-db-ja.com

SpringアノテーションconditionalOnBeanが機能しない

アノテーション構成でクラスを定義しました

    @Configuration
    @AutoConfigureAfter(EndpointAutoConfiguration.class)
    public class EndpointConfiguration {
        @Resource
        private MetricsEndpoint metricsEndpoint;

        @Bean
        public MetricsFormatEndpoint metricsFormatEndpoint() {
            return new MetricsFormatEndpoint(metricsEndpoint);
        }
    }

metricsFormatEndpointはうまく機能します。

しかし、私はアノテーションconditionalOnBeanを使用していますが、まったく機能しません。

    @Bean
    @ConditionalOnBean(MetricsEndpoint.class)
    public MetricsFormatEndpoint metricsFormatEndpoint() {
        return new MetricsFormatEndpoint(metricsEndpoint);
    }

localhost:8080/beansを参照してください。春のapplicationContextにはbean'metricsEndpoint 'があります。

    {"bean":"metricsEndpoint","scope":"singleton",
     "type":"org.springframework.boot.actuate.endpoint.MetricsEndpoint",
     "resource":"class path resource 
    [org/springframework/boot/actuate/autoconfigure/EndpointAutoConfiguration.class]",
    "dependencies":[]}

アノテーション@ConditionalOnBeanのドキュメントを読みましたが、チェックする必要があるBeanのクラスタイプが示されています。指定されたクラスのいずれかが{@linkApplicationContext}に含まれている場合、条件は一致します。

誰が私に理由を教えてくれますか

8
zhangzhide

_@ConditionalOnBean_のjavadocは、次のように説明しています。

Conditionalは、指定されたBeanクラスおよび/または名前がすでにBeanFactoryに含まれている場合にのみ一致します。

この場合、重要な部分は「すでにBeanFactoryに含まれています」です。独自の構成クラスは、自動構成クラスの前に考慮されます。これは、MetricsEndpoint Beanの自動構成が、独自の構成でその存在を確認するまでに行われておらず、その結果、MetricsFormatEndpointBeanが作成されていないことを意味します。 。

取るべき1つのアプローチは、 独自の自動構成クラスを作成するMetricsFormatEndpoint Beanに対して、@AutoConfigureAfter(EndpointAutoConfiguration.class)で注釈を付けることです。これにより、MetricsEndpointBeanが定義された後にその条件が評価されるようになります。

13
Andy Wilkinson

ConditionalOnClassも同様に機能しました。

Javadocは、AutoConfigureAfterは他のspecified auto-configurationクラスの後に適用する必要があると述べています。

また、ConditionalOnClassは、指定されたクラスがクラスパス上にある場合に一致します。私はそれが適切だと思います

0
yiming xie