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 }