@ConditionalOnBean不起作用
结论
1, Spring 是先处理配置类,再加载 Bean的,所以不要@ConditionalOnBean和@Configuration一起用;
2,使用@AutoConfigureAfter指定@Configuration的先后初始化顺序;
参考内容
@AutoConfigureAfter 是有用的,但是 Spring 的配置解析和 Bean 的加载并不是同时发生的,而是有先后的:
//ConfigurationClassPostProcessor.java //第261行 public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { //省略部分代码 //先解析所有的配置 parser.parse(candidates); //省略部分代码 //再根据配置将类加载到Spring中 this.reader.loadBeanDefinitions(configClasses); //省略部分代码 }
从上边的代码可以看到 Spring 是先处理配置类,再加载 Bean 的,所以配置上使用 @ConditionalOnBean 注解,都是无效的。
评论:
自动配置上不能用@ConditionalOnBean注解,就像文章里说的,配置类是先加载的,除非你@ConditionalOnBean里的东西也是个配置类。 Spring的配置类上这个注解能生效是因为其中的那个bean是spring通过注解来引入的(抱歉一时间找不到例子了),通过注解引入的bean在配置类加载的时候就会导入。 在普通类上加@ConditionalOnBean是可以的,但要注意生成的顺序
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 theMetricsEndpoint
bean hasn't happened by the time that your own configuration is checking for its existence and, as a result, yourMetricsFormatEndpoint
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 theMetricsEndpoint
bean has been defined.https://stackoverflow.com/questions/31799855/spring-annotation-conditionalonbean-not-working