Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring annotation conditionalOnBean not working

I defined a class with annotation Configuration

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

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

the MetricsFormatEndpoint works well.

but I use the annotation conditionalOnBean, it doesn't work at all.

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

see the localhost:8080/beans,the spring applicationContext has the 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":[]}

I read the document of the annotation @ConditionalOnBean, it says The class type of bean that should be checked. The condition matches when any of the classes specified is contained in the {@link ApplicationContext}.

who can tell me why

like image 259
zhangzhide Avatar asked Aug 04 '15 02:08

zhangzhide


People also ask

What is @ConditionalOnBean?

The @ConditionalOnBean annotation let a bean be included based on the presence of specific beans. By default Spring will search entire hierarchy ( SearchStrategy.

What is ConditionalOnClass?

Annotation Type ConditionalOnClass@Conditional that only matches when the specified classes are on the classpath. A value() can be safely specified on @Configuration classes as the annotation metadata is parsed by using ASM before the class is loaded.

What is spring boot Autoconfigure?

Spring Boot auto-configuration attempts to automatically configure your Spring application based on the jar dependencies that you have added. For example, If HSQLDB is on your classpath, and you have not manually configured any database connection beans, then we will auto-configure an in-memory database.


1 Answers

The javadoc for @ConditionalOnBean describes it as:

Conditional that only matches when the specified bean classes and/or names are already contained in the BeanFactory.

In this case, the key part is "already contained in the BeanFactory". Your own configuration classes are considered before any auto-configuration classes. This means that the auto-configuration of the MetricsEndpoint bean hasn't happened by the time that your own configuration is checking for its existence and, as a result, your MetricsFormatEndpoint bean isn't created.

One approach to take would be to create your own auto-configuration class for your MetricsFormatEndpoint bean and annotate it with @AutoConfigureAfter(EndpointAutoConfiguration.class). That will ensure that its conditions are evaluated after the MetricsEndpoint bean has been defined.

like image 105
Andy Wilkinson Avatar answered Sep 20 '22 21:09

Andy Wilkinson