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
The @ConditionalOnBean annotation let a bean be included based on the presence of specific beans. By default Spring will search entire hierarchy ( SearchStrategy.
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.
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.
The javadoc for @ConditionalOnBean
describes it as:
Conditional
that only matches when the specified bean classes and/or names are already contained in theBeanFactory
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With