<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    在路上

    路上有驚慌,路上有理想

      BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
      28 Posts :: 1 Stories :: 10 Comments :: 0 Trackbacks

    寫(xiě)在前面的話:spring的監(jiān)聽(tīng)事件模型應(yīng)該是觀察者模式。本人項(xiàng)目里的應(yīng)用在process方法按日期同步某個(gè)庫(kù)的數(shù)據(jù),在方法最后publish一個(gè)event事件,這個(gè)事件用于后續(xù)同步過(guò)來(lái)的數(shù)據(jù)處理。事件處理采用了spring的監(jiān)聽(tīng)模型.這樣可以做到process方法與event可以異步分離執(zhí)行。(注:這個(gè)事件模型缺省使用SyncTaskExecutor來(lái)執(zhí)行l(wèi)istener的注冊(cè)event,所有該listener注冊(cè)的event事件為同步執(zhí)行的)。

    當(dāng)然,spring的這個(gè)機(jī)制還有很多應(yīng)用的場(chǎng)景,就不一一列舉了。

    ApplicationEvent

    事件抽象類(lèi),里面只有一個(gè)構(gòu)造函數(shù)和一個(gè)timestamp。

    ApplicationListener

    監(jiān)聽(tīng)接口,里面只有一個(gè)onApplicationEvent方法。需要用戶(hù)自己編寫(xiě)ApplicationListener的實(shí)現(xiàn)。

    ApplicationContext

    spring上下文,其publishEvent方法用于通知監(jiān)聽(tīng)器(ApplicationListener的實(shí)現(xiàn))注冊(cè)event時(shí)間.

    publishEvent

    void publishEvent(ApplicationEvent event)

    Notify all listeners registered with this application of an application event.

    源碼解讀:
    1.作為ApplicationContext的實(shí)現(xiàn)AbstractApplicationContext.java的成員變量applicationListeners,是一個(gè)ArrayList,保存了所有的ApplicationListener
    2.利用ApplicationEventMulticaster接口里的方法來(lái)完成注冊(cè)監(jiān)聽(tīng)addApplicationListener,移除監(jiān)聽(tīng)removeApplicationListener,removeAllListeners,以及通知監(jiān)聽(tīng)注冊(cè)事件event:multicastEvent(ApplicationEvent event);
    上面說(shuō)到的publishEvent方法即使用了multicastEvent方法

    SimpleApplicationEventMultucaster作為ApplicationEventMulticaster的一個(gè)實(shí)現(xiàn),提供了multicastEvent的實(shí)現(xiàn)代碼,其實(shí)就是迭代所有的監(jiān)聽(tīng)器,用SyncTaskExecutor同步執(zhí)行l(wèi)istener的onApplicationEvent

    public void multicastEvent(final ApplicationEvent event) {

    for (Iterator it = getApplicationListeners().iterator(); it

    .hasNext();) {

    final ApplicationListener listener = (ApplicationListener) it

    .next();

    getTaskExecutor().execute(new Runnable() {

    public void run() {

    listener.onApplicationEvent(event);
    }
    });
    }

    3.注意事項(xiàng):自己編寫(xiě)ApplicationListener的實(shí)現(xiàn)時(shí),要注意不同的監(jiān)聽(tīng)器處理不同的事件(復(fù)寫(xiě)onApplicationEvent)。原因就是multicastEvent的執(zhí)行原理。它是迭代執(zhí)行所有的監(jiān)聽(tīng)器onApplicationEvent

    這里是ApplicationEventMulticaster的類(lèi)分布圖



    abstract public class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster(Code)(Java Doc)
    public interface ApplicationEventMulticaster (Code)(Java Doc)

    public class SimpleApplicationEventMulticaster extends

    這里是ApplicationContext的類(lèi)分布圖
    public class DefaultResourceLoader implements ResourceLoader(Code)(Java Doc)
    public interface ResourceLoader (Code)(Java Doc)

    abstract public class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext,DisposableBean(Code)(Java Doc)
    public interface ConfigurableApplicationContext extends ApplicationContext,Lifecycle(Code)(Java Doc)
    public interface DisposableBean (Code)(Java Doc)

    public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry(Code)(Java Doc)
    public interface BeanDefinitionRegistry (Code)(Java Doc)

    abstract public class AbstractRefreshableApplicationContext extends
    下面是spring自身的事件應(yīng)用
    1) ContextRefreshedEvent:當(dāng)ApplicationContext初始化或者刷新時(shí)觸發(fā)該事件。
    2) ContextClosedEvent:當(dāng)ApplicationContext被關(guān)閉時(shí)觸發(fā)該事件。容器被關(guān)閉時(shí),其管理的所有單例Bean都被銷(xiāo)毀。
    3) RequestHandleEvent:在Web應(yīng)用中,當(dāng)一個(gè)http請(qǐng)求(request)結(jié)束觸發(fā)該事件。
    4) ContestStartedEvent:當(dāng)容器調(diào)用ConfigurableApplicationContext的Start()方法開(kāi)始/重新開(kāi)始容器時(shí)觸發(fā)該事件。
    5) ContestStopedEvent:當(dāng)容器調(diào)用ConfigurableApplicationContext的Stop()方法停止容器時(shí)觸發(fā)該事件。

    posted on 2010-09-01 10:41 阮步兵 閱讀(5358) 評(píng)論(6)  編輯  收藏 所屬分類(lèi): OpenSource

    Feedback

    # re: Spring之事件監(jiān)聽(tīng) 2010-09-01 10:54 @joe
    都有啥有用場(chǎng)景?  回復(fù)  更多評(píng)論
      

    # re: Spring之事件監(jiān)聽(tīng)[未登錄](méi) 2010-09-01 11:30 毛掌柜
    @@joe
    比如在facebook中,一般上傳一張照片都會(huì)對(duì)于一個(gè)activity的產(chǎn)生,這個(gè)時(shí)候就可以用這個(gè)東西。
    記得SimpleApplicationEventMultucaster的listener都是同步執(zhí)行,需要再瞧瞧代碼。。。  回復(fù)  更多評(píng)論
      

    # re: Spring之事件監(jiān)聽(tīng) 2010-09-01 11:41 阮步兵
    getTaskExecutor().execute(new Runnable() {

    public void run() {

    listener.onApplicationEvent(event);
    }
    });
    以上是SimpleApplicationEventMultucaster的部分代碼,它選擇的是new Runnable來(lái)執(zhí)行l(wèi)istener  回復(fù)  更多評(píng)論
      

    # re: Spring之事件監(jiān)聽(tīng) 2010-09-01 11:43 阮步兵
    @@joe
    一個(gè)任務(wù)里面,比如包括上傳文件和數(shù)據(jù)處理,如果文件不必立刻相應(yīng)給客戶(hù),可以通過(guò)事件監(jiān)聽(tīng)的方式來(lái)實(shí)現(xiàn)。另外,業(yè)務(wù)流程中有郵件處理以及日志處理的,都可以在主流程結(jié)束后執(zhí)行,可以選擇事件監(jiān)聽(tīng)方式處理。  回復(fù)  更多評(píng)論
      

    # re: Spring之事件監(jiān)聽(tīng)[未登錄](méi) 2010-09-01 13:20 毛掌柜
    @阮步兵
    看了下Spring 3的代碼,確實(shí)是同步的。
    可以看下SyncTaskExecutor的代碼。  回復(fù)  更多評(píng)論
      

    # re: Spring之事件監(jiān)聽(tīng) 2010-09-01 21:24 阮步兵
    SimpleApplicationEventMultucaster確實(shí)采用的是SyncTaskExecutor同步executor,也就是說(shuō)SimpleApplicationEventMultucaster的listener都是同步執(zhí)行。當(dāng)一個(gè)listener有多個(gè)事件需要處理時(shí),同步執(zhí)行。  回復(fù)  更多評(píng)論
      

    主站蜘蛛池模板: 国产成人无码区免费内射一片色欲| 999zyz**站免费毛片| 亚洲高清国产拍精品熟女| 成人免费视频一区| 亚洲午夜久久久久久尤物| 啦啦啦完整版免费视频在线观看 | 免费黄色网址入口| 未满十八私人高清免费影院| 亚洲成a人片在线观看日本| 中文字幕手机在线免费看电影 | 国产免费看JIZZ视频| 黄色免费网站在线看| 国产免费131美女视频| 亚洲国产精品无码久久久秋霞1| 亚洲性久久久影院| 91热成人精品国产免费| 免费人人潮人人爽一区二区| 亚洲黄色网址大全| 亚洲国产天堂久久综合| 120秒男女动态视频免费| 日日躁狠狠躁狠狠爱免费视频| 亚洲网站在线观看| 亚洲国产精品不卡毛片a在线| j8又粗又长又硬又爽免费视频| 亚洲狠狠狠一区二区三区| 免费看污成人午夜网站| 成在人线av无码免费高潮水| 亚洲色大18成人网站WWW在线播放| 亚洲毛片αv无线播放一区| 69免费视频大片| a级毛片免费网站| 亚洲欧美日韩综合俺去了| 久久国产精品亚洲综合| 无码国产精品一区二区免费虚拟VR| 一级毛片免费在线播放| 久久久久亚洲Av无码专| 国产精品xxxx国产喷水亚洲国产精品无码久久一区| 一级毛片**不卡免费播| 国产精品hd免费观看| 精品韩国亚洲av无码不卡区 | 岛国精品一区免费视频在线观看 |