前面的笔记中,有写过,我们要在spring中声明一个事件监听器,有两种方式,一种是实现ApplicationListener接口,一种是通过@EventListener注解来修饰一个方法,并在该注解中,指定要监听的事件,那这个方法在事件发生的时候,会被回调
这两种机制,我们先说结论:
对于实现接口这种方式,是ApplicationListenerDetector这个类来完成解析的
对于注解这种方式,是EventListenerMethodProcessor和DefaultEventListenerFactory来完成解析的
事件监听器源码流程
其实对于两种实现方式,我们可以认为,在后期的处理过程中,很大一部分逻辑是相同的,只是实现监听器的方式不同而已
上面这个截图是我简单的画了一下对于监听器的处理流程,其实我们所谓的两种实现方式,只是中间的一个小环节而已,或者说只是解析的方式不同罢了,但是后续的处理流程都是一样的
初始化解析类
在前面我有说过,分别是三个类来完成解析的,那我们需要先说下,这三个解析类是在什么时候初始化的
初始化EventListenerMethodProcessor和DefaultEventListenerFactory
对于EventListenerMethodProcessor和DefaultEventListenerFactory这两个类,是在spring源码中,初始化内置后置处理器的时候,添加的
在spring源码:实例化bean的准备工作 这篇博客中,我有写到,在spring初始化的前期准备中,会初始化一些内置的后置处理器,其中,有两个bean,就是EventListenerMethodProcessor和DefaultEventListenerFactory,具体的代码是在:
org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext()
org.springframework.context.annotation.AnnotatedBeanDefinitionReader#AnnotatedBeanDefinitionReader(org.springframework.beans.factory.support.BeanDefinitionRegistry)
org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry)
org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
初始化ApplicationListenerDetector
对于这个bean,是在prepareBeanFactory()方法中,添加了一个后置处理器,就是ApplicationListenerDetector
只是在spring源码中,有两处地方,会添加这个后置处理器,没太理解什么意思
在注册后置处理器的时候,也会添加一遍ApplicationListenerDetector;
org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)
解析@EventListener注解
我们前面说过,对于注解的解析,是由EventListenerMethodProcessor和DefaultEventListenerFactory来完成解析的
我们可以看到这个bean是SmartInitializingSingleton接口的实现类,那我们需要看下,这个接口的afterSingletonsInstantiated()是在什么时候被调用的
org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated
这个接口也是spring的一个扩展点之一,是在spring容器中的bean初始化完成之后,被调用的,具体的地方是在:
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
这个方法,是完成spring容器中beanDefinitionMap转换为spring容器中的bean这步的关键方法,这个方法中,可以分为两部分
1.将beanDefinitionMap中的beanDefinition转换为bean,放入到spring容器中
2.在初始化完成之后,调用smartSingleton.afterSingletonsInstantiated();
所以,我们可以认为,对于@EventListener注解的解析,就是在这里被调用的
org.springframework.context.event.EventListenerMethodProcessor#afterSingletonsInstantiated
@Override
public void afterSingletonsInstantiated() {
/**
* 1.获取到所有的eventListenerFactory,理论上就是DefaultEventListenerFactory
*/
List<EventListenerFactory> factories = getEventListenerFactories();
ConfigurableApplicationContext context = getApplicationContext();
/**
* 2.获取到spring容器中,所有的beanName,依次遍历
*/
String[] beanNames = context.getBeanNamesForType(Object.class);
for