照例先做廣告:去皮兒網(
http://www.qupier.com),每月26日通知你是否中簽。很快要退出廣州的搖號結果通知了。
Seam的Events用的很舒服,spring提供的事件機制太羅嗦,所以起了念頭,著這思路移植一下。最終效果如下:
1 //發布事件
2 Events.instance().fire(eventName,arg1,arg2

.);
3
4 //發布異步事件
5 Events.instance().fireAsynchronous(eventName,arg1,arg2

.);
6
7 //在事務中,發布當事務成功commit時觸發的事件
8 Events.instance().fireOnTransactionSuccess(eventName,arg1,arg2

.);
9
10 //在事務中,發布當事務完成(commit/rollback)時觸發的事件
11 Events.instance().fireOnTransactionCompletion(eventName,arg1,arg2

.);
12
13
14
15 //下面是監聽事件的方式
16
17 //在任意application scope的bean中,在方法上加@Observer注解,同時保證參數列表和發布事件時的參數列表相同:
18 @Observer(eventName)
19 public void someEventListener(A arg1,B arg2){
20 //
..
21 }
22
23 //以上代碼針對的是Events.instance().fireXx方式發布的事件,如果要監聽spring方式發布的事件,可以這么寫:
24 @Observer(type=ContextRefreshedEvent.
class)
25 public void initAll(ContextRefreshedEvent event){
26 //注意參數只能是一個spring的event
27 }
采用如上的方式發布、監聽事件,免去了eventPublisher之類的東西,也免去了event類型的定義。用起來還是比較舒服的。
實現起來也很簡單,系統啟動的時候掃描一遍標記了Observer注解的方法,記錄一下,然后在事件觸發的時候做相應的處理即可。其中,異步事件使用了一個TaskExecutor來完成觸發。比較實用的和事務相關的兩種事件促發方式,使用了spring提供的TransactionSynchronizationManager這個類的靜態方法registerSynchronization,實現起來也很簡單。
附件放上相關的幾個類,其中可能還有些不完善的地方,大伙兒可以看看。
/Files/AllanZ/Events.zip