看Spring源码不得不会的@Enable模块驱动实现原理讲解(二)
如果这两个接口都没有实现,那么就当时一个普通的配置类进行解析。
读完@Import实现的源码,我们再来总结回顾@Import的作用。
@Import注解,就是导入一个配置类,但是这个配置类分为不同的情况。如果这个配置类实现了ImportSelector接口,那么就会调用selectImports方法的实现,获取一批配置类的全限定名,然后再解析配置类;如果实现了@Import注解导入的配置类实现类ImportBeanDefinitionRegistrar,那么就会调用registerBeanDefinitions方法的实现,这个方法可以往容器中注入BeanDefinition;最后如果都没实现,那么就按照一个普通的配置类来解析。
所以基于这么一套配置类解析的规则,就可以实现往容器中注入一些bean,通过这些bean来完成某块功能的实现。
懂了@Enbale模块驱动的基本原理,接下来我们举个例子,来看看@EnbaleAsync注解是如何实现的。
@EnbaleAsync注解上通过@Import注解导入了AsyncConfigurationSelector类
接下来我们进入这个类
一看源码,就发现继承了AdviceModeImportSelector,其实这个类实现了ImportSelector接口,附上源码
其实这个对于ImportSelector接口的实现就是解析注解的属性,然后拿到一个AdviceMode,再调用一个模板方法selectImports,这个方法主要子类来实现,所以我们来看看AsyncConfigurationSelector的实现。
这个adviceMode是注解@EnableAaync注解中的属性mode(),你可以自己翻一下,默认是PROXY,所以这个方法其实就是返回ProxyAsyncConfiguration类的全限定名,其实就是往容器中添加了ProxyAsyncConfiguration配置类。
我们进入这个配置类看一下
其实就是往容器中注入一个AsyncAnnotationBeanPostProcessor,通过名字可以看出这是一个BeanPostProcessor,也就是在bean的生命周期的某个节点来处理@Aysnc注解,如果有不懂BeanPostProcessor的同学可以看看Spring bean到底是如何创建的?(上)和 Spring bean到底是如何创建的?(下)这两篇文章,里面有详细的说明。至于AsyncAnnotationBeanPostProcessor的实现我们就不再继续深究了,有兴趣的同学可以自行点进去看看。
所以说白了,@EnbaleAsync注解的主要作用就是往容器中添加一个可以住了@Async注解的AsyncAnnotationBeanPostProcessor,在bean创建的某个阶段起到作用。
看完@EnableAsync注解的实现,你也可以仿照这个注解的实现来自己实现一个@Enable来实现某个特定的功能。
本文到这里也就结束了。
文章转自公众号:三友的java日记