SpringBoot的条件注解源码解析
文章目录
@ConditionalOnBean、@ConditionalOnMissingBean
写一个配置类测试下@ConditionalOnMissingBean
启动项目
会在ConfigurationClassBeanDefinitionReader#loadBeanDefinitions(Set configurationModel)方法中解析我们的配置类ConditionConfig
在上图中的conditionEvaluator.shouldSkiP就会调用
SpringBootCondition类中的matches方法进行匹配 该方法返回boolean类型
matches方法调用getMatchOutcome方法获取匹配结果
真正的匹配是在OnBeanCondition#getMatchOutcome
@ConditionalOnBean、@ConditionalOnMissingBean和@ConditionalOnSingleCandidate
都是使用这个OnBeanCondition条件类进行匹配的
OnBeanCondition#getMatchOutcome
下面我们看一下具体的匹配逻辑
调用 BeanTypeRegistry# getNamesForType
BeanTypeRegistry类是位于包org.springframework.boot.autoconfigure.condition下的
可以知道它的作用就是便于spring boot条件类OnBeanCondition快速找到bean类型使用的bean类型注册表
上面流程走完也就能得到匹配结果了
这样在ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod_(BeanMethod beanMethod)方法中判断是否需要跳过(conditionEvaluator.shouldSkip)
conditionEvaluator.shouldSkip为true表示应该跳过
为false表示不跳过, 然后执行后面的流程, 把我们的@Bean方法对应的bean就注册进bd map中
总结
@ConditionalOnBean、@ConditionalOnMissingBean和@ConditionalOnSingleCandidate
这三个注解主要是借助 spring boot的条件类OnBeanCondition实现的
这个条件类的作用时机是在注册bd之前进行的(
当然这里说是注册bd之前进行的其实不太严谨,案例中的demo
是把springboot的条件注解用在了@bean方法上面,这个时候确实是在注册bd之前使用条件类。不过如果springboot的条件注解用在了类上面
则是先把bd注册进bd map 然后在根据条件类进行判断 不符合要求就从bd map中移除
)
符合条件就注册为bd不符合就不注册bd