@Condition是Spring中很关键的一个注解,它能够帮助我们只注册符合条件的Bean,我们可以通过配置、容器中的Bean、Java版本等筛选符合bean注册。
1.注解逻辑
以ConditionOnBean为例
@Target({
ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnBeanCondition.class)
public @interface ConditionalOnBean {
}
本质上引入了OnBeanCondition类来进行筛选,而这个类是继承于Condition类来实现的。
@FunctionalInterface
public interface Condition {
/**
* 该方法用于判断该注解条件是否符合,符合返回true
**/
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
2.SpringBoot扩展
SpringBoot为了使这个注解能够更加全面,定义了抽象类SpringBootCondition,所有的条件注解都是继承于此类,但SB提供的所有注解都没有实现matches方法,只有在SpringBootCondition中有,那么我们可以得出其实是使用了模版方法。
@Override
public final boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String classOrMethodName = getClassOrMethodName(metadata);
try {
// 本质通过子类getMatchOutcome来实现具体方法逻辑
ConditionOutcome outcome = getMatchOutcome(context, metadata);
logOutcome(classOrMethodName, outcome);
recordEvaluation(context, classOrMethodName, outcome);
return outcome.isMatch();
}
catch (NoClassDefFoundError ex) {
xxx
}
catch (RuntimeException ex) {
xxx
}
}