日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring5源码 - 13 Spring事件监听机制_@EventListener源码解析

發布時間:2025/3/21 javascript 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring5源码 - 13 Spring事件监听机制_@EventListener源码解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • Pre
  • 概覽
  • 開天辟地的時候初始化的處理器
  • @EventListener
    • EventListenerMethodProcessor
      • afterSingletonsInstantiated
    • 小結
  • 發布事件
  • 附 <異步派發和異常處理器>


Pre

Spring5源碼 - 10 Spring事件監聽機制_應用篇

Spring5源碼 - 11 Spring事件監聽機制_源碼篇

Spring5源碼 - 12 Spring事件監聽機制_異步事件監聽應用及源碼解析

通過上面三篇文章的學習,是不是發現沒有看到Spring是如何解析@EventListener注解的呢? Let’s go ~~~


概覽

Spring容器在啟動的時候初始化EventListenerMethodProcessor和DefaultEventListenerFactory,用于處理@EventListener注解, 調用EventListenerMethodProcessor的afterSingletonsInstantiated方法。


開天辟地的時候初始化的處理器

/*** 處理監聽方法的注解解析器EventListenerMethodProcessor*/if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));}/*** 注冊事件監聽器工廠*/if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));}

一個是注冊一個用于解析@EventListener注解的EventListenerMethodProcessor ,一個是注冊事件監聽工廠。


@EventListener


EventListenerMethodProcessor

我們來看下EventListenerMethodProcessor的類繼承結構

EventListenerMethodProcessor 實現了 EventListenerMethodProcessor,所以執行 BeanFactory 后置處理器時,會調用 postProcessBeanFactory(),將 DefaultEventListenerFactory 添加到緩存中。

可以看到EventListenerMethodProcessor實現了SmartInitializingSingleton接口 , 那肯定要重寫 afterSingletonsInstantiated方法。

我們知道SmartInitializingSingleton接口是在所有的Bean實例化完成以后,Spring回調的方法。 獲取所有的 BeanFactory,找到其中標注了 @EventListener 的方法,利用反射和 DefaultEventListenerFactory 為其創建 ApplicationListener,并添加到事件派發器的緩存中。

refresh----> finishBeanFactoryInitialization(beanFactory);---->preInstantiateSingletons()


afterSingletonsInstantiated

我們看下 EventListenerMethodProcessor的afterSingletonsInstantiated方法

@Overridepublic void afterSingletonsInstantiated() {//從BeanFactory中獲取EventListenerFactory,EventListenerFactory共有2個實現,一個是DefaultEventListenerFactory,對普通的@EventListener進行解析,另一個是TransactionalEventListenerFactory,可以對@TransactionalEventListener進行解析。List<EventListenerFactory> factories = getEventListenerFactories();ConfigurableApplicationContext context = getApplicationContext();// 獲取所有的beanNamesString[] beanNames = context.getBeanNamesForType(Object.class);// 遍歷循環for (String beanName : beanNames) {........// 關鍵:處理bean processBean(factories, beanName, type);.........}}} protected void processBean(final List<EventListenerFactory> factories, final String beanName, final Class<?> targetType) {if (!this.nonAnnotatedClasses.contains(targetType)) {Map<Method, EventListener> annotatedMethods = null;try {//查找帶@EventListener注解的方法annotatedMethods = MethodIntrospector.selectMethods(targetType,new MethodIntrospector.MetadataLookup<EventListener>() {@Overridepublic EventListener inspect(Method method) {return AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class);}});}catch (Throwable ex) {.......}//如果沒有找到帶EventListener注解的方法if (CollectionUtils.isEmpty(annotatedMethods)) {this.nonAnnotatedClasses.add(targetType);........}//否則else {// Non-empty set of methods//遍歷for (Method method : annotatedMethods.keySet()) {for (EventListenerFactory factory : factories) {//EventListenerFactory是否支持對該method的處理if (factory.supportsMethod(method)) {Method methodToUse = AopUtils.selectInvocableMethod(method, this.applicationContext.getType(beanName));// 創建事件監聽器ApplicationListener<?> applicationListener =factory.createApplicationListener(beanName, targetType, methodToUse); if (applicationListener instanceof ApplicationListenerMethodAdapter) {((ApplicationListenerMethodAdapter) applicationListener).init(this.applicationContext, this.evaluator);}// 注冊事件到Context中this.applicationContext.addApplicationListener(applicationListener);break;}}}.......}}}


小結

processBean的主要業務邏輯:

  • 查找帶@EventListener注解的方法 、
  • 不為空的話,遍歷找到的方法
  • 在遍歷方法的循環中,遍歷EventListenerFactory,如果支持,實例化ApplicationListenerMethodAdapter
  • 初始化完成后, 向application中注冊applicationListener

  • 發布事件

    基于@EventListener注解的,發布事件流程和基于接口的一樣,唯一的區別在于

    跟進去走到 listener.onApplicationEvent(event) ,基于注解的會走到 ApplicationListenerMethodAdapter實現類中 onApplicationEvent方法,基于注解的是反射調用,而基于接口的形式是直接調用實現類的onApplicationEvent

    onApplicationEvent調用了processEvent

    反射調用

    基于接口,可以參考我的前面的博客: Spring5源碼 - 10 Spring事件監聽機制_應用篇


    附 <異步派發和異常處理器>

    • 如果事件派發器設置了 Executor,則異步多線程的事件派發
    • 如果事件派發器設置了 ErrorHandler,則用異常處理器來處理異常

    總結

    以上是生活随笔為你收集整理的Spring5源码 - 13 Spring事件监听机制_@EventListener源码解析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。