@ConditionalOnClass、@ConditionalOnMissingClass
这两个注解都有一个@Conditional元注解。
我们重点看下OnClassCondition这个类。对应的matches(…)方法在它的父类-SpringBootCondition中定义。
·
SpringBootCondition#matches(…)
- isMatch() : 获取boolean#match属性值。
`
getClassOrMethodName(…)
获取类名或者类名#方法名。
·
getMatchOutcome(…)
获取匹配的结果。
获取@ConditionalOnClass指定的候选类列表。过滤在类路径中不存在的类。
获取@ConditionalOnMissingClass指定的候选类列表。过滤在类路径中存在的类。
`
getCandidates(…)
获取注解中的属性值列表。
·
filter(…)
过滤不满足条件的class name。
接着看下ClassNameFilter的声明。
PRESENT和MISSING的不同点是match(…)方法的内部实现。一个是isPresent(…),另一个是!isPresent(…)。
对给定类名成功解析的返回true,反之返回false。
获取加载器的顺序如下:
Thread.currentThread().getContextClassLoader()
ClassUtils.class.getClassLoader()
ClassLoader.getSystemClassLoader()
对类的加载。
·
logOutcome(…)
输出相应的日志信息。
·
recordEvaluation(…)
记录并存储相关的信息。
·
match(…)
OnClassCondition本身继承FilteringSpringBootCondition。
也就是说,它也是一个AutoConfigurationImportFilter。而且在spring.factories文件中也有配置。
接下来,我们看下它对于AutoConfigurationImportFilter#match(…)方法的具体实现。
重点看下getOutcomes(…)这个方法。
- createOutcomesResolver(…):创建一个ThreadedOutcomesResolver类型的实例。
接下来分别看下ThreadedOutcomesResolver、StandardOutcomesResolver的resolveOutcomes()方法。
·
StandardOutcomesResolver#resolveOutcomes()
`
`
ClassNameFilter.MISSING.matches(…)方法,我们前面有说过,这里不再分析。
`
ThreadedOutcomesResolver#resolveOutcomes()
在createOutcomesResolver(…)方法有如下代码:
可以看出ThreadedOutcomesResolver封装了StandardOutcomesResolver。
不难看出,它交给了StandardOutcomesResolver解析Outcome。