一.@Conditional条件注解概述
1.作用于方法和类上面,value是实现Condition接口类型,一个判断是否匹配的方法,返回true/false,例如


如果是Windows系统,且@Conditional注解宿主上有@Controller注解时,返回true,对应controller类要加载进容器中实例化,否则false不加载
2.ConditionContext类封装了spring容器的配置和环境信息,通过这个对象可以关联到容器的所有内容,为实现无限扩展提供可能
3.AnnotatedTypeMetadata类,可以简单理解成注解的宿主(因为注解不可能单独存在,必须要有对应宿主),像类、方法、属性等,当然在这里只可能是类和方法
二.原理
1.简单来说,容器启动好刷新的时候,有一个扫描器,对路径下class类进行扫描,如果类上有@Conditional注解,调用其value值对应的接口方法,返回true/false,判断是否将该class加载进容器
2.调用时机是ConfigurationClassPostProcessor BeanFactory后置处理器接口的postProcessBeanDefinitionRegistry方法
3.解析类对象ConfigurationClassParser(构造方法中创建ComponentScanAnnotationParser和ConditionEvaluator),ComponentScanAnnotationParser对象负责扫描class信息,ConditionEvaluator对象负责校验
4.ConditionEvaluator对象封装了spring容器的信息,shouldSkip方法负责注解校验
1).有没有@Conditional注解,没有直接结束true
2).有@Conditional注解,取到注解里value的值,可能有多个@Conditional注解
3).根据value值反射出对应的Condition接口实例对象,多个的话放到集合中,排序
4).循环执行接口方法matches,校验是否匹配
5.条件满足的话,class被解析成ConfigurationClass对象,然后封装成BeanDefinition对象,最后实例化成spring容器中的bean对象
三.springboot中,对@Conditional注解进行扩展
1.@ConditionalOnClass:OnClassCondition(Condition接口实现类)取到spring容器中的类加载器classLoader,加载注解value对应的class,判断是否加载到
2.@ConditionalOnBean:OnBeanCondition(Condition接口实现类)取到spring容器,注解value对应的class名称,判断容器中有没有对应的bean对象
3.@ConditionalOnResource、@ConditionalOnProperty等等,原理都一样
4.FilteringSpringBootCondition、SpringBootCondition是两个抽象模版类,抽取出来公共的逻辑;ConditionOutcome类对匹配结果的封装
四.正是借助于@Conditional注解的扩展,springboot才能实现自动装配,内置很多默认配置进autoconfigure系统,根据条件选择加载进spring容器中