日韩性视频-久久久蜜桃-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源码解析的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    主站蜘蛛池模板: 国产成人高清视频 | 日本一级淫片色费放 | 国产主播在线看 | 美女搞黄在线观看 | 亚洲7777| 麻豆视频在线观看免费网站黄 | 这里只有精品9 | 国内精品久久久久久久影视简单 | 乱子伦一区 | 少妇高潮视频 | 亚洲av无码乱码国产精品 | 亚洲精品9999 | 亚洲女同av | 久久成人在线观看 | mdyd—856冲田杏梨在线 | 日本xxxx高潮少妇 | 国产毛片毛片毛片毛片毛片毛片 | 国产亚洲精品久久久久久青梅 | 成人av免费在线看 | 最新日韩av | 亚洲第1页 | 亚洲av无码一区二区乱子仑 | 少妇光屁股影院 | 亚洲一区二区三区在线免费观看 | 麻豆免费电影 | 边吃奶边添下面好爽 | 亚洲另类在线观看 | 久久久无码一区二区三区 | 伊人久久成人 | 亚洲午夜一区二区 | 国产三级漂亮女教师 | 丰满雪白极品少妇流白浆 | 三度诱惑免费版电影在线观看 | 精品一区二区三区视频在线观看 | 亚洲综合在线五月 | 乱人伦中文字幕 | 理论在线视频 | 免费啪视频 | 久久7777 | 九色国产视频 | 亚洲中文无码av在线 | 欧洲国产精品 | 男女在线观看 | 亚洲午夜剧场 | 国产1区在线观看 | 黑人激情视频 | 欧美另类xxxx野战 | 亚洲乱视频 | 91av毛片| 欧美成欧美va | 日本韩国欧美一区 | 日韩欧美黄色网址 | www.男人的天堂.com | 欧美性猛交xx | 少妇做爰免费理伦电影 | 免费在线观看污 | 天天摸天天干天天操 | 爆乳2把你榨干哦ova在线观看 | 色九月婷婷| 伊人操 | 少妇被按摩师摸高潮了 | 色屁屁影院www国产高清麻豆 | 国产精品天堂 | 成人毛片100免费观看 | 一区二区视频国产 | 天天色天天综合 | 香蕉色网| 日本波多野结衣在线 | 欧美体内she精高潮 日韩一区免费 | 伊人称影院 | 午夜影院福利社 | 欧美岛国国产 | 又粗又猛又爽又黄的视频 | 免费性网站 | 尹人久久| 欧美成人视屏 | 天堂社区av | 日韩精品无码一本二本三本色 | 国产中文字幕视频 | 日韩午夜av | 超碰人人国产 | 爱爱小视频免费看 | 一区二区在线看 | 欧美人妻精品一区二区免费看 | 国精品无码人妻一区二区三区 | 日韩激情床戏 | 在线免费毛片 | 蜜桃av在线看 | www.三区 | 99热这里只有精品5 国产精品伦子伦免费视频 精品一二三 | 中文久久久久 | 一级性生活毛片 | 免费视频久久 | 中文字幕亚洲不卡 | 成人黄色三级 | 最新黄色网址在线观看 | 欧美成人黄色 | 亚洲精品第三页 | 亚洲欧美第一 |