這篇文章帶給大家的內容是關於Spring事件機制源碼的詳細分析,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
前言:由於之前使用Spring事件機制出現了問題,所以特意去了解這塊的源碼。 Spring事件機制其實就是事件發布/訂閱(注意在Spring中訂閱指的是監聽)。
PS:Spring版本為5.1.5.RELEASE
原始碼分析
初始化
初始化這塊關鍵是核心元件的註冊
1、ApplicationEventPublisher的初始化與註冊,關鍵方法為AbstractApplicationContext的方法prepareBeanFactory()
2、ApplicationEventMulticaster的初始化與註冊,關鍵方法為AbstractApplicationContext的initApplicationEvent#Multicaster()方法方法ApplicationListener的初始化與註冊,關鍵方法為AbstractApplicationContext的registerListeners()方法
這塊不細說,感興趣的可以自行追蹤關鍵方法
#事件發布/訂閱事件發布/訂閱的關鍵方法為AbstractApplicationContext的publishEvent,原始碼如下:
protected void publishEvent(Object event, ResolvableType eventType) { // 避免空指针 Assert.notNull(event, "Event must not be null"); if (logger.isTraceEnabled()) { logger.trace("Publishing event in " + getDisplayName() + ": " + event); } // 处理event对象,将其转换为ApplicationEvent ApplicationEvent applicationEvent; if (event instanceof ApplicationEvent) { applicationEvent = (ApplicationEvent) event; } else { applicationEvent = new PayloadApplicationEvent<Object>(this, event); if (eventType == null) { eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType(); } } // 是否延迟多播,即将事件发布到所有监听器中 if (this.earlyApplicationEvents != null) { this.earlyApplicationEvents.add(applicationEvent); } else { //此处为事件监听处理器的调用关键 getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType); } // 是否将事件发布到父容器中 if (this.parent != null) { if (this.parent instanceof AbstractApplicationContext) { ((AbstractApplicationContext) this.parent).publishEvent(event, eventType); } else { this.parent.publishEvent(event); } } }
透過程式碼跟踪,發現Spring中使用ApplicationEventMulticaster的預設實作SimpleApplicationEventMulticaster來觸發事件的監聽,關鍵方法為multicastEvent()方法,原始碼如下:
@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) {//线程池不为null,则异步调用监听器 executor.execute(new Runnable() { @Override public void run() { invokeListener(listener, event); } }); } else {// 同步调用监听器 invokeListener(listener, event); } } }
這篇文章到這裡就已經全部結束了,更多其他精彩內容可以關注PHP中文網的
Java視頻教程#以上是Spring事件機制源碼的詳細分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!