從名字上看知道IoFilter應(yīng)該是一個(gè)過濾器,不錯(cuò),它確實(shí)是一個(gè)過濾器,它和Servlet中的過濾器類似,主要用于攔截和過濾I/O操作中的各種信息。在Mina的官方文檔中已經(jīng)提到了IoFilter的作用:
?。?)記錄事件的日志(這個(gè)在本文中關(guān)于LoggingFilter的講述中會(huì)提到) (2)測(cè)量系統(tǒng)性能 ?。?)信息驗(yàn)證 ?。?)過載控制 (5)信息的轉(zhuǎn)換 (例如:編碼和解碼,這個(gè)會(huì)在關(guān)于ProtocolCodecFilter的講述中會(huì)提到) ?。?)和其他更多的信息 還是上一篇文檔一樣,先提出幾個(gè)問題,然后沿著這幾個(gè)問題的思路一個(gè)一個(gè)的對(duì)IoFilter進(jìn)行講解。 ?。?)什么時(shí)候需要用到IoFilter,如果在自己的應(yīng)用中不添加過濾器可以嗎? (2)如果在IoService中添加多個(gè)過濾器可以嗎?若可以,如何進(jìn)行添加,這多個(gè)過濾器是如何工作的? (3)Mina中提供了協(xié)議編、解碼器,IoFilter也可以實(shí)現(xiàn)IO數(shù)據(jù)的編解碼功能,在實(shí)際的使用中如何選擇? 在開始對(duì)上面的問題進(jìn)行討論前,為了對(duì)IoFilter提供的方法有一個(gè)具體的了解,先對(duì)Mina自身提供的一個(gè)最簡(jiǎn)單的過濾器進(jìn)行一些講解----LoggingFilter(源碼在附件中,配有中文翻譯)。 首先還是看一下LoggingFilter中提供的幾個(gè)方法。列舉如下(方法中的參數(shù)就不再給出,完整方法的實(shí)現(xiàn)請(qǐng)參考附件中LoggingFilter的源碼): ?。?)sessionCreated() ?。?)sessionOpened() ?。?)sessionClosed() (4)sessionIdle() ?。?)exceptionCaught() (6)messageReceived() ?。?)messageSent() ?。?)filterWrite() ?。?)filterClose() 這幾個(gè)方法都由相應(yīng)會(huì)話(或者說是連接的狀態(tài),讀、寫、空閑、連接的開閉等)的狀態(tài)的改變來觸發(fā)的。當(dāng)一個(gè)會(huì)話開啟時(shí),LoggingFilter捕獲到會(huì)話開啟的事件,會(huì)觸發(fā)sessionCreated()方法,記錄該會(huì)話開啟的日志信息。同樣當(dāng)一個(gè)會(huì)話發(fā)送數(shù)據(jù)時(shí),Logging捕獲到會(huì)話發(fā)送消息的事件會(huì)記錄消息發(fā)送的日志信息。這里只是給出messageReceived()的完成方法的實(shí)現(xiàn),其他方法的完整實(shí)現(xiàn)請(qǐng)參考附件中 LoggingFilter的源碼。
LoggingFilter繼承與 IoFilterAdpater,IoFilterAdpater是IoFilter的一個(gè)實(shí)現(xiàn)類,該類只是提供了IoFilter方法的簡(jiǎn)單實(shí)現(xiàn) ----將傳遞到各方法中的消息轉(zhuǎn)發(fā)到下一個(gè)過濾器中。你可以根據(jù)自己的需求繼承IoFilterAdpater,并重寫相關(guān)的方法。 LoggingFilter就是重寫了上面提到的幾個(gè)方法,用于記錄當(dāng)前的會(huì)話各種操作的日志信息。通過上面的例子,我們可以大體的了解了 IoFilter的基本功能:根據(jù)當(dāng)前會(huì)話狀態(tài),來捕獲和處理當(dāng)前會(huì)話中所傳遞的消息。 IoFilter的UML圖如下: 從上面的類圖我們可以清晰的看到IoFilter是一個(gè)接口,它有兩個(gè)具體的實(shí)現(xiàn)類: IoFilterAdpater:該類提供了IoFilter所有方法的方法體,但是沒有任何邏輯處理,你可以根據(jù)你具體的需求繼承該類,并重寫相關(guān)的方法。IoFilterAdpater是在過濾器中使用的較多的一個(gè)類。 ReferenceCountingIoFilter:該類封裝IoFilter的實(shí)例,它使用監(jiān)視使用該IoFilter的對(duì)象的數(shù)量,當(dāng)沒有任何對(duì)象使用該IoFilter時(shí),該類會(huì)銷毀該IoFilter。 IoFilterAdpater有三個(gè)子類,它們的作用分別如下: LoggingFilter:日志工具,該類處理記錄IoFilter每個(gè)狀態(tài)觸發(fā)時(shí)的日志信息外不對(duì)數(shù)據(jù)做任何處理。它實(shí)現(xiàn)了IoFilter接口的所有方法。你可以通過閱讀該類的源碼學(xué)習(xí)如何實(shí)現(xiàn)你自己的IoFilter。 ExcuterFilter:這個(gè)Mina自身提供的一個(gè)線程池,在 Mina中你可以使用這個(gè)類配置你自己的線程池,由于創(chuàng)建和銷毀一個(gè)線程,需要耗費(fèi)很多資源,特別是在高性能的程序中這點(diǎn)尤其重要,因此在你的程序中配置一個(gè)線程池是很重要的。它有助于你提高你的應(yīng)用程序的性能。關(guān)于配置Mina的線程池在后續(xù)的文檔中會(huì)給出詳細(xì)的配置方法。 ProtocolFilter:該類是Mina提供的一個(gè)協(xié)議編解碼器,在socket通信中最重要的就是協(xié)議的編碼和解碼工作,Mina提供了幾個(gè)默認(rèn)的編解碼器的實(shí)現(xiàn),在下面的例子中使用了 ObjectSerializationCodecFactory,這是Mina提供的一個(gè)Java對(duì)象的序列化和反序列化方法。使用這個(gè)編解碼器,你可以在你的Java客戶端和服務(wù)器之間傳遞任何類型的Java對(duì)象。但是對(duì)于不同的平臺(tái)之間的數(shù)據(jù)傳遞需要自己定義編解碼器,關(guān)于這點(diǎn)的介紹會(huì)在后續(xù)的文檔中給出。 為了更加清楚的理解這個(gè)過濾器的作用我們先來看一個(gè)簡(jiǎn)單的例子,這個(gè)例子的功能就是服務(wù)器在客戶端連接到服務(wù)器時(shí)創(chuàng)建一個(gè)會(huì)話,然后向客戶端發(fā)送一個(gè)字符串(完整的源碼在附件中,這里只給出程序的簡(jiǎn)要內(nèi)容): Java代碼
其中ServerMain和ClientMain分別是服務(wù)器和客戶端的主程序,ServerHandler和ClientHandler是服務(wù)器和客戶端的數(shù)據(jù)處理句柄,關(guān)于IoHandler會(huì)在后面的文檔中做詳細(xì)的講解,這里只是簡(jiǎn)單說明一下,IoHandler主要是對(duì)數(shù)據(jù)進(jìn)行邏輯操作,也可以理解為程序的業(yè)務(wù)邏輯層。其中: Java代碼
這行代碼的功能是將網(wǎng)絡(luò)傳輸中的數(shù)據(jù)在發(fā)送時(shí)編碼成二進(jìn)制數(shù)據(jù),解碼時(shí)將二進(jìn)制數(shù)據(jù)還原成一個(gè)對(duì)象或者是基本類型的數(shù)據(jù)。 Java代碼
|
|