publishEvent->multicastEvent()解析 使用场景

使用场景:

  1、异步处理,比如订单完成后想异步发送消息

  2、事件告知,比如想知道spring容器是否启动完成,那么就可以监听spring启动完成后的事件

  3、扩展处理,比如监听 跑完步 这个事件,接着会喝水。考虑到后面可能跑完步还要去吃饭,那么可以通过监听同一个事件来完成。

省的还需要改原来的代码。代码也解耦了。

       4、模块解耦,减少模块之间的依赖。解耦维度是模块

 

 1     
 2 //推送事件到响应的监听器
 3     protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
 4         Assert.notNull(event, "Event must not be null");
 5 
 6         // Decorate event as an ApplicationEvent if necessary
 7         ApplicationEvent applicationEvent;
 8         if (event instanceof ApplicationEvent) {
 9             applicationEvent = (ApplicationEvent) event;
10         }
11         else {
12             applicationEvent = new PayloadApplicationEvent<>(this, event);
13             if (eventType == null) {
14                 eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
15             }
16         }
17 
18         // Multicast right now if possible - or lazily once the multicaster is initialized
19         if (this.earlyApplicationEvents != null) {
20             this.earlyApplicationEvents.add(applicationEvent);
21         }
22         else {
23         //使用事件广播器广播事件到对应的监听器
24             getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
25         }
26 
27         // Publish event via parent context as well...
28         if (this.parent != null) {
29             if (this.parent instanceof AbstractApplicationContext) {
30                 ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
31             }
32             else {
33                 this.parent.publishEvent(event);
34             }
35         }
36     }
37 
38 
39         @Override
40     public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
41         ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
42         Executor executor = getTaskExecutor();
43         // getApplicationListeners(event, type)返回与给定事件类型匹配的应用监听器集合
44         //实现监听事件,实现ApplicationListener接口就行    
45         //自定义监听事件,继承ApplicationContextEvent,通过ApplicationEventPublisher发布就行
46         for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
47             if (executor != null) {
48                 executor.execute(() -> invokeListener(listener, event));
49             }
50             else {
51                 invokeListener(listener, event);
52             }
53         }
54     }
55 
56 
57 
58         private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
59         try {
60         //触发监听器的onApplicationEvent,入参为给定的事件
61             listener.onApplicationEvent(event);
62         }
63         catch (ClassCastException ex) {
64             String msg = ex.getMessage();
65             if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
66                 // Possibly a lambda-defined listener which we could not resolve the generic event type for
67                 // -> let's suppress the exception and just log a debug message.
68                 Log logger = LogFactory.getLog(getClass());
69                 if (logger.isTraceEnabled()) {
70                     logger.trace("Non-matching event type for listener: " + listener, ex);
71                 }
72             }
73             else {
74                 throw ex;
75             }
76         }
77     }

 

posted @ 2021-05-27 11:24  龙之谷2019  阅读(698)  评论(0编辑  收藏  举报