applicationcontext事件機制是觀察者設計模式的實作,通過applicationevent類和applicationlistener接口,可以實作applicationcontext事件處理。如果容器中有一個applicationlistener bean,每當applicationcontext釋出applicationevent時,applicationlistener bean将自動被觸發。
spring的事件架構有如下兩個重要的成員:
applicationevent:容器事件,必須由applicationcontext釋出
applicationlistener:監聽器,可由容器中的任何監聽器bean擔任
實際上,spring的事件機制與所有時間機制都基本相似,它們都需要事件源、事件和事件監聽器組成。隻是此處的事件源是applicationcontext,且事件必須由java程式顯式觸發。下面的程式将示範spring容器的事件機制。程式先定義了一個applicationevent類,其對象就是一個spring容器事件。代碼如下:
<a href="http://my.oschina.net/itblog/blog/203744#">?</a>
1
2
3
4
5
6
7
8
9
10
11
12
13
<code>public</code> <code>class</code> <code>emailevent </code><code>extends</code> <code>applicationevent{</code>
<code> </code><code>private</code> <code>string address;</code>
<code> </code><code>private</code> <code>string text;</code>
<code> </code><code>public</code> <code>emailevent(object source, string address, string text){</code>
<code> </code><code>super</code><code>(source);</code>
<code> </code><code>this</code><code>.address = address;</code>
<code> </code><code>this</code><code>.text = text;</code>
<code> }</code>
<code> </code><code>public</code> <code>emailevent(object source) {</code>
<code> </code><code>super</code><code>(source);</code>
<code> </code><code>//......address和text的setter、getter</code>
<code>}</code>
上面的emailevent類繼承了applicationevent類,除此之外,它就是一個普通的java類。
容器事件的監聽器類必須實作applicationlistener接口,實作該接口就必須實作如下方法:
onapplicationevent(applicationevent event):每當容器内發生任何事件時,此方法都會被觸發
本例所使用的容器監聽器類代碼如下:
<code>public</code> <code>class</code> <code>emailnotifier </code><code>implements</code> <code>applicationlistener{</code>
<code> </code><code>public</code> <code>void</code> <code>onapplicationevent(applicationevent event) {</code>
<code> </code><code>if</code> <code>(event </code><code>instanceof</code> <code>emailevent) {</code>
<code> emailevent emailevent = (emailevent)event;</code>
<code> system.out.println(</code><code>"郵件位址:"</code> <code>+ emailevent.getaddress());</code>
<code> system.our.println(</code><code>"郵件内容:"</code> <code>+ emailevent.gettext());</code>
<code> } </code><code>else</code> <code>{</code>
<code> system.our.println(</code><code>"容器本身事件:"</code> <code>+ event);</code>
<code> }</code>
将監聽器配置在spring的容器中,代碼如下:
<code><</code><code>bean</code> <code>class</code><code>=</code><code>"com.abc.emailnotifier"</code> <code>/></code>
為spring容器注冊監聽器,不需要像awt程式設計那樣采用代碼進行注冊,隻需要在spring的配置檔案中進行簡單配置即可。當我們住唉spring中配置了一個實作了applicationlistener的bean,spring容器就會把這個bean當成容器事件的監聽器。
當系統建立spring容器、加載spring容器時會自動觸發容器事件,容器事件監聽器可以監聽到這些事件。除此之外,程式也可以調用applicationcontext的publishevent()方法來主動觸發一個容器事件,如下是一個例子:
<code>public</code> <code>class</code> <code>springtest {</code>
<code> </code><code>public</code> <code>static</code> <code>void</code> <code>main(string args[]){</code>
<code> applicationcontext context = </code><code>new</code> <code>classpathxmlapplicationcontext(</code><code>"bean.xml"</code><code>);</code>
<code> </code><code>//建立一個applicationevent對象</code>
<code> emailevent event = </code><code>new</code> <code>emailevent(</code><code>"hello"</code><code>,</code><code>"[email protected]"</code><code>,</code><code>"this is a test"</code><code>);</code>
<code> </code><code>//主動觸發該事件</code>
<code> context.publishevent(event);</code>
注意:如果bean想釋出事件,則bean必須獲得其容器的引用。如果程式中沒有直接擷取容器的引用,則應該讓bean實作applicationcontextaware或者beanfactoryaware接口,進而可以獲得容器的引用。
spring提供如下幾個内置事件:
contextrefreshedevent:applicationcontext容器初始化或重新整理時觸發該事件。此處的初始化是指:所有的bean被成功裝載,後處理bean被檢測并激活,所有singleton bean 被預執行個體化,applicationcontext容器已就緒可用
contextstartedevent:當使用configurableapplicationcontext(applicationcontext的子接口)接口的start()方法啟動applicationcontext容器時觸發該事件。容器管理聲明周期的bean執行個體将獲得一個指定的啟動信号,這在經常需要停止後重新啟動的場合比較常見
contextclosedevent:當使用configurableapplicationcontext接口的close()方法關閉applicationcontext時觸發該事件
contextstoppedevent:當使用configurableapplicationcontext接口的stop()方法使applicationcontext容器停止時觸發該事件。此處的停止,意味着容器管理生命周期的bean執行個體将獲得一個指定的停止信号,被停止的spring容器可再次調用start()方法重新啟動
requesthandledevent:web相關事件,隻能應用于使用dispatcherservlet的web應用。在使用spring作為前端的mvc控制器時,當spring處理使用者請求結束後,系統會自動觸發該事件。