上篇我们讲到实现事件监听可以使用实现ApplicationListener接口 Spring中ApplicationListener -【Spring底层原理】,如果有多个方法需要监听事件,那岂不是每个方法都要放在类中实现ApplicationListener接口,这样并不是很方便,所以spring为我们提供了另外一种方式实现事件监听:使用@EventListener注解
一、注解用法
注解源码如下,有如下作用:
- 可以作用在方法
- 参数可以是class数组,可以写多个事件
- 使用了该注解的方法,当容器中发布事件后,该方法会触发,类似实现ApplicationListener接口
1 | java复制代码 /* |
从注释可以看到是使用EventListenerMethodProcessor
这个处理器来解析方法上的EventListener
注解,EventListenerMethodProcessor
主要则是通过其实现的接口SmartInitializingSingleton
来进行处理的,后面会分析其源码。
二、实例分析
1 | java复制代码// 启动测试类 |
运行启动类,可以看到,两个事件都被触发了,使用@EventListener注解,方便让多个方法触发
三、源码分析
上面讲到是使用EventListenerMethodProcessor
这个处理器来解析方法上的EventListener注解,点进EventListenerMethodProcessor
查看,发现实现了SmartInitializingSingleton
接口,主要就是通过该接口实现的。
1 | java复制代码public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware, BeanFactoryPostProcessor {} |
1 | java复制代码public interface SmartInitializingSingleton { |
SmartInitializingSingleton
接口有个afterSingletonsInstantiated
方法,当单实例bean全部创建完成,会触发这个接口,执行afterSingletonsInstantiated
方法,类似于ContextRefreshedEvent
我们在afterSingletonsInstantiated
方法上打上断点,看看源码是何时调用该方法执行的。
通过方法调用栈,容器创建对象,调用refresh()方法刷新容器——>finishBeanFactoryInitialization(beanFactory)——>preInstantiateSingletons()初始化剩下的单实例bean
- 创建所有的单实例bean
- 获取所有创建好的单实例bean,判断各bean是否是SmartInitializingSingleton类型的
- 如果是则调用afterSingletonsInstantiated方法
这里便到了我们上面分析的SmartInitializingSingleton#afterSingletonsInstantiated方法,也就是@EventListener注解注解起作用的地方
1 | java复制代码@Override |
四、总结
- IOC容器创建对象并refresh刷新
- finishBeanFactoryInitialization(beanFactory)——>preInstantiateSingletons()初始化剩下的单实例bean
- 创建所有的单实例bean
- 获取所有创建好的单实例bean,判断各bean是否是SmartInitializingSingleton类型的
- 如果是则调用afterSingletonsInstantiated方法
本文转载自: 掘金