基于Class的条件注解
@ConditionalOnClass或者@ConditionalOnMissingClass注解对应的条件类是OnClassCondition,定义如下:
@Order(Ordered.HIGHEST_PRECEDENCE) // 优先级、最高级别
class OnClassCondition extends SpringBootCondition {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) {
StringBuffer matchMessage = new StringBuffer(); // 记录匹配信息
MultiValueMap<String, Object> onClasses = getAttributes(metadata,
ConditionalOnClass.class); // 得到@ConditionalOnClass注解的属性
if (onClasses != null) { // 如果属性存在
List<String> missing = getMatchingClasses(onClasses, MatchType.MISSING,
context); // 得到在类加载器中不存在的类
if (!missing.isEmpty()) { // 如果存在类加载器中不存在对应的类,返回一个匹配失败的ConditionalOutcome
return ConditionOutcome
.noMatch("required @ConditionalOnClass classes not found: "
+ StringUtils.collectionToCommaDelimitedString(missing));
}
// 如果类加载器中存在对应的类的话,匹配信息进行记录
matchMessage.append("@ConditionalOnClass classes found: "
+ StringUtils.collectionToCommaDelimitedString(
getMatchingClasses(onClasses, MatchType.PRESENT, context)));
}
// 对@ConditionalOnMissingClass注解做相同的逻辑处理(说明@ConditionalOnClass和@ConditionalOnMissingClass可以一起使用)
MultiValueMap<String, Object> onMissingClasses = getAttributes(metadata,
ConditionalOnMissingClass.class);
if (onMissingClasses != null) {
List<String> present = getMatchingClasses(onMissingClasses, MatchType.PRESENT,
context);
if (!present.isEmpty()) {
return ConditionOutcome
.noMatch("required @ConditionalOnMissing classes found: "
+ StringUtils.collectionToCommaDelimitedString(present));
}
matchMessage.append(matchMessage.length() == 0 ? "" : " ");
matchMessage.append("@ConditionalOnMissing classes not found: "
+ StringUtils.collectionToCommaDelimitedString(getMatchingClasses(
onMissingClasses, MatchType.MISSING, context)));
}
// 返回全部匹配成功的ConditionalOutcome
return ConditionOutcome.match(matchMessage.toString());
}
private enum MatchType { // 枚举:匹配类型。用于查询类名在对应的类加载器中是否存在。
PRESENT { // 匹配成功
@Override
public boolean matches(String className, ConditionContext context) {
return ClassUtils.isPresent(className, context.getClassLoader());
}
},
MISSING { // 匹配不成功
@Override
public boolean matches(String className, ConditionContext context) {
return !ClassUtils.isPresent(className, context.getClassLoader());
}
};
public abstract boolean matches(String className, ConditionContext context);
}
}