1、@Conditional简介

@Conditional注解指示组件仅在所有指定条件匹配时才有资格注册。@Conditional注解的value属性就是条件匹配Class对象,具体说是Condition接口实例数组。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME) @Documented public @interface Conditional {
//必须匹配的所有条件才能注册组件 Class<? extends Condition>[] value(); }
@Conditional注释可以以下任何方式使用:

* 作为任何直接或间接用@Component注释的类的类型级注释,包括@Configuration类
* 作为一个元注释,用于编写自定义构造型注释
* 作为任何@Bean方法的方法级注释

如果@Configuration类标记为@Conditional,则与该类关联的所有@Bean方法、@Import注释和@ComponentScan注释都将受这些条件的约束。

下面在看一下接口Condition的定义。
@FunctionalInterface public interface Condition { //确定条件是否匹配。 boolean
matches(ConditionContext context, AnnotatedTypeMetadata metadata); }
2、原理分析

在SpringFramework中@Conditional注释背后的处理器是ConditionEvaluator,通过跟踪源码发现共有三处使用了到了ConditionEvaluator:

*
ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(BeanMethod)
解析@Bean方法
* ConfigurationClassParser.processConfigurationClass(ConfigurationClass)
解析@Configuration类
* ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClass,
SourceClass) 中解析被@ComponentScan注解的类

这三处使用ConditionEvaluator的原理一样,ConditionEvaluator的shouldSkip()方法返回一个boolean值,true代表跳过被注解组件的注册或解析,下面就是第二种的实现。

ConditionEvaluator的实现。
public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable
ConfigurationPhase phase) { if (metadata == null ||
!metadata.isAnnotated(Conditional.class.getName())) { return false; } if (phase
== null) { if (metadata instanceof AnnotationMetadata &&
ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata)
metadata)) { return shouldSkip(metadata,
ConfigurationPhase.PARSE_CONFIGURATION); } return shouldSkip(metadata,
ConfigurationPhase.REGISTER_BEAN); } List<Condition> conditions = new
ArrayList<>(); for (String[] conditionClasses : getConditionClasses(metadata))
{ for (String conditionClass : conditionClasses) { Condition condition =
getCondition(conditionClass, this.context.getClassLoader());
conditions.add(condition); } } AnnotationAwareOrderComparator.sort(conditions);
for (Condition condition : conditions) { ConfigurationPhase requiredPhase =
null; if (condition instanceof ConfigurationCondition) { requiredPhase =
((ConfigurationCondition) condition).getConfigurationPhase(); }
//有一个condition返回false就跳过类的解析或注册 if ((requiredPhase == null || requiredPhase ==
phase) && !condition.matches(this.context, metadata)) { return true; } } return
false; }
 

 

技术
©2019-2020 Toolsou All rights reserved,
STM32的内部温度传感器实验总结。JLink、STLink、DAPLink、CMSIS DAP使用区别Linux 常用的命令vue-loader+webpack项目配置《剑指offer刷题笔记》6、重建二叉树 【c++详细题解】pycharm中安装cv2失败,及其解决数据库基础-MySql8.0(第二篇)--DML和DQLpython模拟阴阳师抽卡CSS实现loading小动画二维哈希(矩阵哈希)