spring事件監聽機制
阿新 • • 發佈:2018-09-03
ide could 事情 task object 負責 his try and
事件機制的主要成員:
- 事件
- 事件監聽器(監聽事件觸發,處理一些事情)
- 事件源(發布事件)
javaSE 提供了一系列自定義事件的標準。
EvenObject,為javaSE提供的事件類型基類,任何自定義事件都必須繼承它。
EventListener,為javaSE提供的事件監聽器基類,任何自定義事件監聽器都得實現。
javaSE未提供事件發布者,由各個應用程序自行實現事件發布者這一角色。
spring提供了ApplicationEventPublisher接口作為事件發布者,並且ApplicationContext接口繼承了該接口,擔當著事件發布者的角色。但ApplicationContext接口的具體實現各有差異。
spring提供了ApplicationEventMulticaster接口,負責管理ApplicationListener和發布ApplicationEvent。ApplicationContext接口會把事件的相關工作委托給ApplicationEventMulticaster的實現類做,
spring事件機制流程:
- ApplicationContext發布事件
//發布事件 context.publishEvent(event);
實際上是由ApplicationContext的實現AbstractApplicationContext執行發布事件的行為
- 找到事件廣播器,廣播事件
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
- 執行SimpleApplicationEventMulticaster中的multicastEvent方法,調用事件監聽器的onApplicationEvent()方法
@Override public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) { ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event)); for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) { Executor executor = getTaskExecutor(); if (executor != null) { executor.execute(new Runnable() { @Override public void run() { invokeListener(listener, event); } }); } else { invokeListener(listener, event); } } }
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) { ErrorHandler errorHandler = getErrorHandler(); if (errorHandler != null) { try { doInvokeListener(listener, event); } catch (Throwable err) { errorHandler.handleError(err); } } else { doInvokeListener(listener, event); } } @SuppressWarnings({"unchecked", "rawtypes"}) private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) { try { listener.onApplicationEvent(event); } catch (ClassCastException ex) { String msg = ex.getMessage(); if (msg == null || matchesClassCastMessage(msg, event.getClass().getName())) { // Possibly a lambda-defined listener which we could not resolve the generic event type for // -> let‘s suppress the exception and just log a debug message. Log logger = LogFactory.getLog(getClass()); if (logger.isDebugEnabled()) { logger.debug("Non-matching event type for listener: " + listener, ex); } } else { throw ex; } } }
自定義事件Demo
- 自定義事件
package com.spring.event.event; import org.springframework.context.ApplicationEvent; import com.spring.event.bean.Notify; /** * 自定義事件 * @author sxq * @time 2018年8月31日 上午10:26:24 * */ public class NotifyEvent extends ApplicationEvent { private int version; private Notify notify; public int getVersion() { return version; } public void setVersion(int version) { this.version = version; } /** * serialVersionUID */ private static final long serialVersionUID = -6198589267233914254L; public NotifyEvent(Object source) { super(source); } public Notify getNotify() { return notify; } public void setNotify(Notify notify) { this.notify = notify; } public NotifyEvent(Object source,Notify notify) { this(source); this.notify = notify; } }
- 自定義監聽器
package com.spring.event.listner; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; import com.spring.event.event.NotifyEvent; /** * 自定義監聽器 * @author sxq * @time 2018年8月31日 上午10:27:04 * */ @Component public class NotifyListenr implements ApplicationListener<NotifyEvent>{ @Override public void onApplicationEvent(NotifyEvent event) { System.out.println(event.getNotify().toString()); //監聽事件後,處理後續事情 } }
- 發布
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Notify notify = new Notify("李四",21); NotifyEvent event = new NotifyEvent("NotifyEvent",notify); event.setVersion(100); //發布事件 context.publishEvent(event);
spring事件監聽機制