SpringBoot的条件注解源码解析

SpringBoot的条件注解源码解析

@ConditionalOnBean、@ConditionalOnMissingBean

写一个配置类测试下@ConditionalOnMissingBean
image.png

image.png
image.png

启动项目
会在ConfigurationClassBeanDefinitionReader#loadBeanDefinitions(Set configurationModel)方法中解析我们的配置类ConditionConfig
image.png
image.png

在上图中的conditionEvaluator.shouldSkiP就会调用
SpringBootCondition类中的matches方法进行匹配 该方法返回boolean类型

matches方法调用getMatchOutcome方法获取匹配结果
真正的匹配是在OnBeanCondition#getMatchOutcome

@ConditionalOnBean、@ConditionalOnMissingBean和@ConditionalOnSingleCandidate
都是使用这个OnBeanCondition条件类进行匹配的

OnBeanCondition#getMatchOutcome

下面我们看一下具体的匹配逻辑
image.png

image.png
image.png

调用 BeanTypeRegistry# getNamesForType

BeanTypeRegistry类是位于包org.springframework.boot.autoconfigure.condition下的
可以知道它的作用就是便于spring boot条件类OnBeanCondition快速找到bean类型使用的bean类型注册表
image.png
image.png
image.png

上面流程走完也就能得到匹配结果了

这样在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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值