上篇文章讲了ConfigurationClassPostPreocessor类生成BeanDefinition的时机、以及概括了它做的事,它是整个注解开发的支撑,今天来具体细品。
1.看ConfigurationClassPostPreocessor类的postProcessorBeanDefinitionRegistry()方法
2.进入processConfigBeanDefinitions()方法
2.1进入checkConfigurationClassCandidate()方法
这个方法就是获取BeanDefinition的metadata,从metadata中获取注解信息判断是full匹配还是lite匹配,如果都不是,说明这个BeanDefinition不需要处理。返回false。
进入isConfigurationCandidate()方法,这个方法就是收集哪些注解是lite匹配。
candidateIndicators容器如下:
endi.........
接着processConfigBeanDefinitions()方法继续往下看
2.2进入parse()方法
在进入parse()方法,注意把metadata和beanName封装成了一个ConfigurationClass,然后把ConfigurationClass作为参数传进去了
进入processConfigurationClass()方法如下,如果shouldSkip()方法返回true,那么流畅就结束了,不需要处理。
进入shouldSkip()方法
3.根据这个代码就知道@Conditional注解该怎么应用
@Conditional注解的value是一个Condition类型的Class对象或数组
自定义一个注解,使用@Conditional注解,如下:
可以知道OnPropertyCondition必须是一个Condition类型的,创建OnPropertyCondition类实现Condition接口,如下:
Condition接口有一个返回boolean类型的match()方法,根据上面源码中的shouldSkip()源码知道,如果match()返回false那么流程就结束了,那么就没有生成BeanDefinition,就无法实例化,创建一个类使用自定义注解
ConditionBean类上加了我们自定义的注解,而我们的自定义注解使用了一个@Conditional注解,在match方法中进行了一些逻辑处理,去获取属性文件以ConditionOnProperty的name为key的值是否为true,如果为true,则match方法返回true,否则返回false,如果属性文件中cn.enjoy.flag为false,那么ConditionBean是无法实例化的。
测试:
把属性文件中cn.enjoy.flag改为true
在测试
获取到了实例。