精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Spring-Context注解源碼之@EventListener

開發 前端
EventListenerMethodProcessor的processBean方法中,會遍歷已經注冊的所有的bean,找到包含有被 @EventListener 標注的方法。這些方法會被遍歷已經創建的 EventListenerFactory 找到合適的工廠來生成 applicationListener,并將 applicationListener 注冊到容器的事件監聽器列表。

[[410307]]

 注解說明

Annotation that marks a method as a listener for application events.

以注解的方式將一個方法標記為事件監聽器。如果對于spring事件監聽機制還不了解的小伙伴點擊查看一文徹底搞懂spring事件監聽機制

屬性說明

  1. public @interface EventListener { 
  2.  
  3.    /** 
  4.     * 同class 
  5.     */ 
  6.    @AliasFor("classes"
  7.    Class<?>[] value() default {}; 
  8.  
  9.    /** 
  10.     * 監聽事件的類型 
  11.     * 如果這個屬性長度不為空,則以這個屬性的為準 
  12.     * 如果這個屬性長度為空,則以被標注方法的參數為準 
  13.     */ 
  14.    @AliasFor("value"
  15.    Class<?>[] classes() default {}; 
  16.  
  17.    /** 
  18.     * 以spring表達的方式計算事件監聽是否需要觸發 
  19.     */ 
  20.    String condition() default ""
  21.  

通過上述屬性,我們可以發現,相比起實現接口的方式創建事件監聽器,用注解的方式靈活性更加大,不僅可以指定多個接受事件類型,還可以增加是否觸發的條件。

使用示例

  1. @EventListener 
  2. public void customListener1(MyEvent event) { 
  3.     System.out.println("接受事件customListener1"); 

相關源碼

EventListenerMethodProcessor

  1. /** 
  2.  * 檢測bean里面是否包含 @EventListener 
  3.  */ 
  4. private void processBean(final String beanName, final Class<?> targetType) { 
  5.    if (!this.nonAnnotatedClasses.contains(targetType) && 
  6.          !targetType.getName().startsWith("java") && 
  7.          !isSpringContainerClass(targetType)) { 
  8.  
  9.       Map<Method, EventListener> annotatedMethods = null
  10.       try { 
  11.          // 找到所有包含 @EventListener 的方法 
  12.          annotatedMethods = MethodIntrospector.selectMethods(targetType, 
  13.                (MethodIntrospector.MetadataLookup<EventListener>) method -> 
  14.                      AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class)); 
  15.       } 
  16.       catch (Throwable ex) { 
  17.          // An unresolvable type in a method signature, probably from a lazy bean - let's ignore it. 
  18.          if (logger.isDebugEnabled()) { 
  19.             logger.debug("Could not resolve methods for bean with name '" + beanName + "'", ex); 
  20.          } 
  21.       } 
  22.  
  23.       if (CollectionUtils.isEmpty(annotatedMethods)) { 
  24.          // 如果這個類一個包含 @EventListener 方法都沒有則緩存到 nonAnnotatedClasses 中,減少重復計算 
  25.          this.nonAnnotatedClasses.add(targetType); 
  26.          if (logger.isTraceEnabled()) { 
  27.             logger.trace("No @EventListener annotations found on bean class: " + targetType.getName()); 
  28.          } 
  29.       } 
  30.       else { 
  31.          // Non-empty set of methods 
  32.          ConfigurableApplicationContext context = this.applicationContext; 
  33.          Assert.state(context != null"No ApplicationContext set"); 
  34.          // 可以創建自定義 EventListenerFactory,如果不創建,默認擁有 DefaultEventListenerFactory 
  35.          List<EventListenerFactory> factories = this.eventListenerFactories; 
  36.          Assert.state(factories != null"EventListenerFactory List not initialized"); 
  37.          for (Method method : annotatedMethods.keySet()) { 
  38.             for (EventListenerFactory factory : factories) { 
  39.                // 對于每一個方法遍歷所有的工廠,找到一個支持的工廠就進入創建并完成遍歷 
  40.                if (factory.supportsMethod(method)) { 
  41.                   // 根據方法創建 applicationListener,并將 applicationListener 添加給容器 
  42.                   Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName)); 
  43.                   ApplicationListener<?> applicationListener = 
  44.                         factory.createApplicationListener(beanName, targetType, methodToUse); 
  45.                   if (applicationListener instanceof ApplicationListenerMethodAdapter) { 
  46.                      ((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator); 
  47.                   } 
  48.                   context.addApplicationListener(applicationListener); 
  49.                   break; 
  50.                } 
  51.             } 
  52.          } 
  53.          if (logger.isDebugEnabled()) { 
  54.             logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" + 
  55.                   beanName + "': " + annotatedMethods); 
  56.          } 
  57.       } 
  58.    } 

EventListenerMethodProcessor的processBean方法中,會遍歷已經注冊的所有的bean,找到包含有被 @EventListener 標注的方法。這些方法會被遍歷已經創建的 EventListenerFactory 找到合適的工廠來生成 applicationListener,并將 applicationListener 注冊到容器的事件監聽器列表。

ApplicationListenerMethodAdapter

  1. /** 
  2.  * 解析時間監聽器支持的事件類型 
  3.  */ 
  4. private static List<ResolvableType> resolveDeclaredEventTypes(Method method, @Nullable EventListener ann) { 
  5.    int count = method.getParameterCount(); 
  6.    if (count > 1) { 
  7.       // 如果方法本身參數超過1個,則直接拋出異常 
  8.       throw new IllegalStateException( 
  9.             "Maximum one parameter is allowed for event listener method: " + method); 
  10.    } 
  11.  
  12.    if (ann != null) { 
  13.       // 取出 注解中的 classes屬性 
  14.       Class<?>[] classes = ann.classes(); 
  15.       if (classes.length > 0) { 
  16.          // 如果classes屬性不為空,則解析classes屬性并返回作為事件解析類型 
  17.          List<ResolvableType> types = new ArrayList<>(classes.length); 
  18.          for (Class<?> eventType : classes) { 
  19.             types.add(ResolvableType.forClass(eventType)); 
  20.          } 
  21.          return types; 
  22.       } 
  23.    } 
  24.  
  25.    // 如果傳入的classes屬性為空,并且方法沒有參數,也拋出異常 
  26.    if (count == 0) { 
  27.       throw new IllegalStateException( 
  28.             "Event parameter is mandatory for event listener method: " + method); 
  29.    } 
  30.    return Collections.singletonList(ResolvableType.forMethodParameter(method, 0)); 

ApplicationListenerMethodAdapter的resolveDeclaredEventTypes方法會解析@EventListener標簽的classes屬性,然后根據這個屬性決定事件監聽器的監聽的事件類型。

如果方法參數個數超過1個,直接拋出異常。這是一個事件觸發以后,如果接受的方法參數個數大于1個,spring沒辦法給方法進行傳參。

如果classes屬性為空,并且方法參數個數為0個,也拋出異常。這是因為spring無法推斷這個監聽器需要支持什么類型的事件。

除去上面兩種情況,解析都是成功,同時classes屬性會優先被選擇為監聽的事件類型。

  1. private boolean shouldHandle(ApplicationEvent event, @Nullable Object[] args) { 
  2.    if (args == null) { 
  3.       return false
  4.    } 
  5.    String condition = getCondition(); 
  6.    if (StringUtils.hasText(condition)) { 
  7.      // 如果 condition 屬性不為空,則進行spring表達式計算結果并返回 
  8.       Assert.notNull(this.evaluator, "EventExpressionEvaluator must not be null"); 
  9.       return this.evaluator.condition( 
  10.             condition, event, this.targetMethod, this.methodKey, args, this.applicationContext); 
  11.    } 
  12.    return true

ApplicationListenerMethodAdapter的shouldHandle方法會根據@EventListener標簽的condition屬性判斷是否需要推送消息。

如果condition不為空,則使用spring表達式計算condition得到結果,結果為true的時候才推送事件。如果condition為空,則不判斷直接推送。

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2023-04-10 11:00:00

注解Demo源碼

2023-07-10 08:43:53

SpringIDEA

2022-02-19 07:41:36

Bean注解項目

2022-02-20 07:28:13

Spring注解用法

2022-12-07 08:02:43

Spring流程IOC

2022-05-30 11:17:44

Spring容器配置

2022-06-09 07:27:14

JavaSpring容器

2019-09-09 06:30:06

Springboot程序員開發

2020-12-20 10:02:17

ContextReactrender

2023-05-08 08:11:49

@Component使用場景時序圖

2020-10-14 06:23:54

SpringBean實例化

2009-06-15 17:48:32

Spring注解注入屬性

2011-04-15 09:44:45

Spring

2023-06-02 16:24:46

SpringBootSSM

2021-08-27 07:38:21

AndroidDialogContext

2015-03-31 18:26:43

陌陌社交

2017-08-02 14:44:06

Spring Boot開發注解

2021-03-08 00:11:02

Spring注解開發

2022-06-07 07:58:45

SpringSpring AOP

2021-03-11 11:14:39

鴻蒙HarmonyOS應用
點贊
收藏

51CTO技術棧公眾號

午夜精品久久久久久久| 国产精品资源网| 亚洲网站在线观看| 五月天视频在线观看| 亚洲欧美成人影院| 91视频免费播放| 成人激情视频在线观看| 国产大片中文字幕在线观看| 综合色就爱涩涩涩综合婷婷| 欧美精品v国产精品v日韩精品| 国产精品videossex国产高清| 免费在线高清av| 国产一区二区三区日韩| 欧美专区在线观看| 国产人妻精品一区二区三区不卡| 四虎5151久久欧美毛片| 制服视频三区第一页精品| 国产极品在线视频| 免费成人黄色| 久久精品一区四区| 俄罗斯精品一区二区| 中文字幕日本人妻久久久免费 | 日本最新中文字幕| 日韩精品影视| 亚洲精品中文字| 色哟哟网站在线观看| 国产一区高清| 色综合天天做天天爱| 蜜桃网站在线观看| 天天在线视频色| 久久久久高清精品| 国产精品一区二区免费| 999国产精品视频免费| 日本亚洲视频在线| 日本亚洲欧美成人| 日韩欧美不卡视频| 亚洲婷婷免费| 欧美成人在线免费| 日韩在线一卡二卡| 日韩大片在线播放| 中文字幕欧美精品日韩中文字幕| 亚洲最大的黄色网| 激情小说一区| 亚洲第一天堂av| 极品白嫩的小少妇| 51亚洲精品| 日韩一区二区免费在线电影| 午夜国产福利在线观看| 99riav视频一区二区| 色综合天天综合在线视频| 成年人观看网站| 男人久久天堂| 色婷婷久久99综合精品jk白丝| 欧美极品欧美精品欧美| 538在线精品| 天天综合日日夜夜精品| 久久久久久久久久网| 国产色播av在线| 丁香五六月婷婷久久激情| 亚洲 高清 成人 动漫| www在线看| 懂色av一区二区三区| 777久久久精品一区二区三区| 免费一二一二在线视频| 色狠狠综合天天综合综合| 美女一区二区三区视频| 久久不卡日韩美女| 91精品国产aⅴ一区二区| 91av免费观看| 超碰97久久| 亚洲毛片在线观看.| 法国空姐电影在线观看| 99精品在线免费在线观看| 久久在线视频在线| 久久国产在线观看| 国产一区二区你懂的| 人体精品一二三区| 中文字字幕在线观看| 国内精品国产三级国产a久久| 99久久精品久久久久久ai换脸| 老牛影视av牛牛影视av| 久久久久国产一区二区三区四区| 图片区小说区区亚洲五月| 精品欧美色视频网站在线观看| 亚洲国产人成综合网站| 日av中文字幕| 精品国产第一国产综合精品| 亚洲成人精品视频在线观看| 法国空姐电影在线观看| 伊人青青综合网| 91精品国产高清久久久久久91| 欧美brazzers| 国产盗摄精品一区二区三区在线| 精品国产乱码久久久久久郑州公司 | 日韩视频一区二区三区在线播放| 亚洲色图欧美日韩| 日韩理论片av| 国内精品久久久久久影视8| 精品久久久久久久久久久久久久久久久久| 精品在线你懂的| 激情小说综合网| 免费av网站在线观看| 午夜精品一区二区三区免费视频| 污片在线免费看| www.爱久久| 综合国产在线观看| 日韩精品在线不卡| 精品一区二区三区免费| 黄色小网站91| 18videosex性欧美麻豆| 在线看日本不卡| 手机免费看av片| 97精品97| 国产精品一区二区久久久| 蜜臀av午夜精品| 亚洲乱码中文字幕| 日韩精品一区二区三区不卡| а√中文在线天堂精品| 日韩在线观看免费高清| 精品免费囯产一区二区三区 | 精品欧美色视频网站在线观看| 日韩人体视频一二区| 午夜影院福利社| 91不卡在线观看| 国产精品美女视频网站| 手机亚洲第一页| 亚洲人被黑人高潮完整版| 欧美精品成人网| 要久久电视剧全集免费| 欧美激情亚洲一区| 精品久久久久久亚洲综合网站| 中文字幕免费一区| 久久人妻精品白浆国产| 欧美激情久久久久久久久久久| 九九热精品视频| 国产毛片一区二区三区va在线| 国产精品美女一区二区| 亚洲综合在线网站| 国产精品三级| 日韩美女主播视频| 精品无吗乱吗av国产爱色| 欧美日韩国产专区| 加勒比精品视频| 国产亚洲毛片在线| 精品欧美一区二区三区久久久 | 国产精品pans私拍| 可以在线观看的av| 色哟哟国产精品| 熟女少妇一区二区三区| 日韩一级大片| 精品一区久久久| 蜜臀久久精品| 亚洲人成五月天| 国产天堂第一区| 国产精品色眯眯| 在线能看的av网站| 久久福利影院| 亚洲a在线观看| 香蕉久久aⅴ一区二区三区| 日韩欧美在线网站| 麻豆成人在线视频| 高清shemale亚洲人妖| 国产美女主播在线| 天天操综合520| 国产精品久久久999| 香蕉视频国产在线观看| 91精品国产乱码| 日本最新中文字幕| 国产亚洲福利社区一区| 国产九九热视频| 自拍日韩欧美| 久久99精品久久久久子伦| 在线视频超级| 中文字幕亚洲专区| www日本在线| 狠狠躁夜夜躁人人爽超碰91| 中字幕一区二区三区乱码| 精品一区二区三区免费播放| 成人在线视频一区二区三区| 天堂网av成人| 成人一区二区电影| 草草在线视频| 在线一区二区日韩| www日本高清视频| 色哟哟在线观看一区二区三区| 91制片厂在线| 成人不卡免费av| 依人在线免费视频| 一区在线免费观看| 天堂精品视频| 国产一区二区av在线| 欧美一级在线亚洲天堂| 男女啪啪在线观看| 精品伊人久久97| 国产乱淫av片免费| 日韩欧美精品网站| 欧美成人aaa片一区国产精品| 99久久综合99久久综合网站| 日本精品一区在线观看| 亚洲乱码精品| 欧美日本韩国在线| 麻豆国产一区| 国产精品免费一区二区三区都可以 | 国产精品久久久网站| 国产精品免费一区豆花| 黄毛片在线观看| 美女av一区二区| 国产裸舞福利在线视频合集| 精品日本一线二线三线不卡| 中文字幕精品一区二| 精品国产精品三级精品av网址| 中文字幕五月天| 国产亚洲欧美色| 国产伦精品一区二区三区妓女| 国产在线精品一区二区三区不卡| 可以在线看的黄色网址| 亚洲国产日本| 黑人巨大国产9丨视频| 欧美裸体在线版观看完整版| 美女一区视频| 精品综合久久88少妇激情| 91在线精品播放| 欧美高清你懂的| 国产成人涩涩涩视频在线观看 | 欧美在线二区| 亚洲自拍三区| 大片网站久久| 日韩欧美99| 国产欧美一区| 欧洲精品久久| 欧美精品momsxxx| 久久精品人成| 色婷婷综合久久久久久| 国产视频在线观看一区| 一区中文字幕电影| 91九色极品视频| 国产精品美女久久久久| 国产欧美在线播放| 午夜精品久久久久久毛片| 国产精品久久久久久久久影视 | xxx在线播放| 久久香蕉国产线看观看99| 日本japanese极品少妇| av在线这里只有精品| chinese麻豆新拍video| 成人黄色国产精品网站大全在线免费观看 | 国产视频精品免费播放| 天堂а√在线8种子蜜桃视频| 亚洲第一视频网站| 午夜影院在线视频| 亚洲精品永久免费精品| 激情在线视频| 中文字幕成人在线| 欧美成人三区| 蜜臀久久99精品久久久无需会员| 成人影院在线观看| 久久精品99国产精品酒店日本| 九七久久人人| 久久久久久久久久久91| 天天综合av| 国产精品成人免费电影| 性欧美video另类hd尤物| 亚洲aa中文字幕| 欧美韩一区二区| 污视频在线免费观看一区二区三区| 婷婷综合视频| 久久成人福利视频| 久久精品一区二区国产| 超碰av在线免费观看| 九九国产精品视频| 风韵丰满熟妇啪啪区老熟熟女| www.欧美精品一二区| 精品无码国产污污污免费网站 | 国产黄色一区| 91黄色精品| 亚洲黄页网站| 自拍亚洲欧美老师丝袜| 黄色成人av网站| 日本一区二区黄色| 久久99国产精品久久| 丰满岳乱妇一区二区| 国产视频911| 欧美黑人猛猛猛| 欧美色图在线视频| 91中文字幕在线播放| 亚洲精品一区二区三区福利 | 日韩aaa久久蜜桃av| 亚洲mv在线看| 日韩午夜高潮| 亚洲第一成肉网| 99re热这里只有精品视频| www.涩涩爱| 午夜电影网一区| 97精品久久人人爽人人爽| 亚洲成人xxx| 蜜桃视频在线观看www社区 | 亚洲 欧美 成人| 日韩欧美一级片| 国产在线视频网站| 欧美激情一区二区久久久| 精品成人av| 国产中文一区二区| 久久精品影视| av免费网站观看| thepron国产精品| 欧美色图亚洲视频| 欧洲精品一区二区| 可以免费看毛片的网站| 理论片在线不卡免费观看| 日韩精品第一| 麻豆视频成人| 亚洲一级影院| 一级做a爱视频| 亚洲国产电影在线观看| 国产成人无码一区二区在线播放| 日韩午夜电影av| 色网站免费在线观看| 日本久久久a级免费| 精品国产乱子伦一区二区| 热这里只有精品| 美女在线一区二区| 四虎国产精品成人免费入口| 婷婷激情综合网| 欧美一级特黄aaaaaa大片在线观看| 久久精品久久久久电影| 国产精品字幕| 日韩av影视| 久久久久久久高潮| 不卡一区二区在线观看| 五月天国产精品| 日韩中文字幕免费在线观看| 欧美成人免费视频| 国产精品日本一区二区三区在线 | 国产麻豆乱码精品一区二区三区| 久久精品亚洲欧美日韩精品中文字幕| 激情视频综合网| 国产三级久久久| 国产精品第6页| 亚洲性生活视频| 亚洲欧美在线成人| 午夜一区二区三视频在线观看| 久久欧美肥婆一二区| 色婷婷在线影院| 色欧美片视频在线观看 | 久久综合久久88| 国产成年精品| 日韩a级黄色片| 成人动漫中文字幕| av黄色在线看| 亚洲人成啪啪网站| 国产美女久久| 午夜在线视频免费观看| 国产精品一级在线| 国产亚洲欧美精品久久久久久| 亚洲电影免费观看高清| 九色porny自拍视频在线观看| 久久久一本精品99久久精品66| 天堂成人国产精品一区| 微拍福利一区二区| 欧美蜜桃一区二区三区| 亚洲区欧洲区| 激情一区二区三区| 视频一区欧美日韩| 少妇高潮一区二区三区喷水| 777亚洲妇女| 成人性生交大片免费看网站| 久久久99爱| 日本中文一区二区三区| 中文字幕电影av| 精品国精品自拍自在线| 国产伦精品一区二区三区视频金莲| 日韩成人在线资源| 国产一区欧美一区| 日本熟妇一区二区| 国产亚洲欧美视频| 久久国际精品| 精品99在线视频| 亚洲视频 欧洲视频| 欧美天堂在线视频| 国产精品电影久久久久电影网| 国产精品久久天天影视| 精品久久久久久无码人妻| 色婷婷一区二区| 丝袜在线观看| 日本一区视频在线观看免费| 国内精品伊人久久久久av一坑| 久久9999久久免费精品国产| 亚洲日本中文字幕| 日本成人手机在线| 蜜臀av午夜一区二区三区| 亚洲同性gay激情无套| 五月婷婷丁香网| 91日韩在线播放| 美女日韩在线中文字幕| 国内偷拍精品视频| 亚洲性无码av在线| 久久久久高潮毛片免费全部播放| jizz欧美激情18| 精品欧美aⅴ在线网站| www.欧美日本韩国|