目錄:
ioc容器beandefinition-spring 原始碼(1)
ioc容器依賴注入-spring 原始碼(2)
ioc容器beanpostprocessor-spring 原始碼(3)
事件機制-spring 原始碼(4)
事件源觸發事件後,將事件通知給***,***執行相應邏輯的過程
使用簡單的實現:
事件:
public***:class eatevent extends
private
string status;
public
string getstatus()
public
void
setstatus(string status)
public
eatevent(object source)
}
public觸發事件:public
void
system.out.println("收到通知,可以去吃飯了");}}
public以上**是實際spring專案中經常會用到的,利用spring的事件機制,可以解耦各個具體***,在變化的需求中通過增減***來減少具體實現的改動。class testdo implements
private
public
void
dotest()
public
bean***ception
}
spring核心是管理bean,而對於這種事件機制,天然有了比較好的實現基礎,可以想象這些事件bean在初始化時已經被管理器加入到某個登錄檔裡了,然後事件觸發時,就要找容器觸發。
原始碼實現部分:
publicvoid
publishevent(event,
null);}
protected
void
publishevent(object event, resolvabletype eventtype)
//if (event instanceof
}else}//
multicast right now if possible - or lazily once the multicaster is initialized
)
else
//publish event via parent context as well...
if (this.parent != null
)
else}}
protectedvoid
configurablelistablebeanfactory beanfactory =getbeanfactory();
//if
class
);
if(logger.isdebugenabled())
}else}}
publicobject source =event.getsource();void multicastevent(final
resolvabletype type = (eventtype != null ?eventtype : resolvedefaulteventtype(event));
executor executor =gettaskexecutor();
if (executor != null
) });
}else}}
class
> sourcetype = (source != null ? source.getclass() : null
); listenercachekey cachekey = new
listenercachekey(eventtype, sourcetype);
//quick check for existing entry on concurrenthashmap...
listenerretriever retriever = this
.retrievercache.get(cachekey);
if (retriever != null
)
if (this.beanclassloader == null ||(classutils.iscachesafe(event.getclass(),
this.beanclassloader) &&(sourcetype == null || classutils.iscachesafe(sourcetype, this
.beanclassloader))))
retriever = new listenerretriever(true
);
//獲取監聽者
//進快取
this
.retrievercache.put(cachekey, retriever);
return
listeners;}}
else}
resolvabletype eventtype, class
>sourcetype, listenerretriever retriever)
//遍歷全部監聽者,過濾出匹配的
if(supportsevent(listener, eventtype, sourcetype))
alllisteners.add(listener);}}
if (!listenerbeans.isempty())
alllisteners.add(listener);}}
}catch
(nosuchbeandefinitionexception ex) }}
annotationawareordercomparator.sort(alllisteners);
return
alllisteners;}
最下面的annotationawareordercomparator.sort用來排序監聽者的執行順序。繼承ordered即可。
這裡我們可以回顧一下這個refresh方法的具體**。
這裡牽涉到同步執行或非同步執行這些***的問題,預設spring是同步執行的,那麼在實際場景中我們會因為監聽者執行影響住流程,採用非同步的方式,如果沒有閱讀過原始碼,採取的方式可能會使用在publish的時候進行非同步化。
executor executor =gettaskexecutor();if (executor != null
) });
}
publicprivate taskexecutor taskexecutor = new
taskexecutor()
};
protected
taskexecutor gettaskexecutor()
}
protected另外,回到最前面的例子中,注意eatevent中那個source屬性,代表**的意思,再呼叫publish方法時將this傳入,那麼在篩選監聽者的時候,就可以判斷是哪個**的bean發起的通知,再進行一次篩選是否執行的邏輯,如此就是監聽者可以過濾事件源了。void
errorhandler errorhandler =geterrorhandler();
if (errorhandler != null
)
catch
(throwable err)
}else
}
事件機制 Spring 原始碼系列(4)
目錄 ioc容器beandefinition spring 原始碼 1 ioc容器依賴注入 spring 原始碼 2 ioc容器beanpostprocessor spring 原始碼 3 事件機制 spring 原始碼 4 事件源觸發事件後,將事件通知給 執行相應邏輯的過程 使用簡單的實現 事件 ...
事件機制 Spring 原始碼系列(4)
目錄 ioc容器beandefinition spring 原始碼 1 ioc容器依賴注入 spring 原始碼 2 ioc容器beanpostprocessor spring 原始碼 3 事件機制 spring 原始碼 4 事件源觸發事件後,將事件通知給 執行相應邏輯的過程 使用簡單的實現 事件 ...
事件機制 Spring 原始碼系列(4)
目錄 ioc容器beandefinition spring 原始碼 1 ioc容器依賴注入 spring 原始碼 2 ioc容器beanpostprocessor spring 原始碼 3 事件機制 spring 原始碼 4 事件源觸發事件後,將事件通知給 執行相應邏輯的過程 使用簡單的實現 事件 ...