J2EE架構(gòu)綜述

J2EE(Java 2 Platform Enterprise Edition)即Java2平臺(tái)企業(yè)版,是一套全新的技術(shù)架構(gòu),便于企業(yè)級(jí)用戶規(guī)范化高效率地開(kāi)發(fā)企業(yè)級(jí)web服務(wù)。(Java一共有三個(gè)發(fā)行版本,分別是J2SE,J2EE,J2ME。分別代表Java的標(biāo)準(zhǔn)版本,企業(yè)版本和精簡(jiǎn)版本,我們文章中指的是第二個(gè)版本)

通常來(lái)講企業(yè)級(jí)用戶面對(duì)Web時(shí)的需求是多樣化的,我們重點(diǎn)關(guān)注企業(yè)級(jí)用戶的Web系統(tǒng)的開(kāi)發(fā),從架構(gòu)上描述一個(gè)Web系統(tǒng)所具有的層次。

無(wú)論基于什么樣的技術(shù)體系,Web都是基于B/S的模式,即瀏覽器/服務(wù)器。不同的技術(shù)體系的區(qū)別僅在于Server(服務(wù)器)端,我們將從宏觀和微觀兩個(gè)尺度來(lái)梳理服務(wù)器端的架構(gòu)。

宏觀上,我們把服務(wù)器端分為應(yīng)用層和底層兩個(gè)層次。應(yīng)用層指的是承擔(dān)業(yè)務(wù)邏輯的服務(wù)器,而底層指數(shù)據(jù)庫(kù)服務(wù)器。它們的關(guān)系如下圖所示:



在數(shù)據(jù)庫(kù)服務(wù)器中我們安裝相應(yīng)的數(shù)據(jù)庫(kù)軟件,像sqlserver,mysql,oracle等。根據(jù)我們具體的Web業(yè)務(wù)需求構(gòu)建數(shù)據(jù)庫(kù),在數(shù)據(jù)庫(kù)服務(wù)器中建立其相應(yīng)的數(shù)據(jù)表。

接下來(lái),著重說(shuō)一下Web服務(wù)器中的架構(gòu)問(wèn)題,也就是從微觀上來(lái)看J2EE的架構(gòu)。Web服務(wù)器中的代碼是由Java編寫的。從程序設(shè)計(jì)的角度來(lái)講也可以分為應(yīng)用層程序和底層程序,通常距離用戶越近距離底層就越遠(yuǎn)。在Web服務(wù)器中底層的代碼一般都是與數(shù)據(jù)庫(kù)的連接與操作,系統(tǒng)的安全性相關(guān)的代碼,這些程序與用戶距離較遠(yuǎn)。而應(yīng)用層程序則與用戶距離很近基本上與用戶只隔一層前端界面,應(yīng)用層的程序主要用來(lái)處理一些業(yè)務(wù)邏輯,例如注冊(cè),登錄,給用戶展現(xiàn)界面等等。抽象地看,Web服務(wù)器內(nèi)部的程序分層如下圖:



上圖表示的是在Web服務(wù)器中程序的一般架構(gòu),采取的是軟件設(shè)計(jì)中常用的MVC設(shè)計(jì)模式。接下來(lái)讓我們從底層向頂層梳理一遍服務(wù)器程序的結(jié)構(gòu)。

數(shù)據(jù)持久層

最右邊是我們的數(shù)據(jù)庫(kù)系統(tǒng)或者說(shuō)數(shù)據(jù)庫(kù)服務(wù)器。它是整個(gè)系統(tǒng)的基石,全部的系統(tǒng)都構(gòu)建于數(shù)據(jù)庫(kù)之上。Web服務(wù)器通過(guò)數(shù)據(jù)庫(kù)連接與數(shù)據(jù)庫(kù)產(chǎn)生聯(lián)系。在Web服務(wù)器中為了追求程序的高內(nèi)聚性,我們一般把取得數(shù)據(jù)庫(kù)連接當(dāng)做一個(gè)獨(dú)立的模塊來(lái)完成。在這個(gè)模塊中J2EE為我們提供了現(xiàn)成的數(shù)據(jù)庫(kù)驅(qū)動(dòng)讓我們可以非常簡(jiǎn)便地與數(shù)據(jù)庫(kù)建立連接,當(dāng)然這是原生的做法。但是考慮到獲取數(shù)據(jù)庫(kù)連接是一個(gè)相對(duì)比較耗時(shí)的操作,如果當(dāng)需求來(lái)臨時(shí)才向數(shù)據(jù)庫(kù)取得連接無(wú)疑會(huì)降低系統(tǒng)的并發(fā)性,影響用戶的體驗(yàn)。因此,我們可以在系統(tǒng)啟動(dòng)時(shí)就與數(shù)據(jù)庫(kù)建立好若干連接,將這些暫時(shí)用不到的連接放置于一個(gè)“池”中。當(dāng)需求來(lái)臨時(shí),我們直接從“池”中取得連接與數(shù)據(jù)庫(kù)進(jìn)行交互,這提高了系統(tǒng)的響應(yīng)速度,在這里我們可以使用第三方的框架c3p0來(lái)建立一個(gè)數(shù)據(jù)庫(kù)連接池。

再往左就是數(shù)據(jù)庫(kù)的操作模塊,通常無(wú)論我們的需求再怎么復(fù)雜反映到對(duì)數(shù)據(jù)庫(kù)的操作上就是增,刪,改,查四大基本操作的變換組合。因此同樣是為了追求系統(tǒng)的高內(nèi)聚性,我們把增,刪,改,查四個(gè)操作歸并到一起,做成一個(gè)通用性很高的模塊,達(dá)到無(wú)論什么樣的更改或是無(wú)論查詢出什么樣的結(jié)構(gòu)化數(shù)據(jù)都可以使用這個(gè)模塊來(lái)進(jìn)行處理。這個(gè)模塊在設(shè)計(jì)時(shí)就較多的利用到了Java中著名的反射機(jī)制。在這個(gè)操作模塊中,我們仔細(xì)思考就能發(fā)現(xiàn),對(duì)數(shù)據(jù)庫(kù)的增,刪,改操作是一類操作,而對(duì)數(shù)據(jù)庫(kù)的查詢又是一類操作。因?yàn)榍罢卟⒉粫?huì)返回結(jié)構(gòu)化的數(shù)據(jù),只會(huì)返回操作成功與否的結(jié)果,而后者數(shù)據(jù)庫(kù)會(huì)返回結(jié)構(gòu)化的數(shù)據(jù)。因此在數(shù)據(jù)庫(kù)操作模塊中,只會(huì)細(xì)分為兩個(gè)子模塊。

再往上就出現(xiàn)了四個(gè)獨(dú)立的模塊,這里先說(shuō)DAO模塊。DAO(Data Access Object)即數(shù)據(jù)訪問(wèn)對(duì)象。在這個(gè)模塊中我們真正把對(duì)數(shù)據(jù)庫(kù)的操作具體化了,我們所熟知的SQL語(yǔ)句就是在這里寫明的。在這個(gè)模塊中我們針對(duì)不同的數(shù)據(jù)庫(kù)實(shí)體編寫不同的數(shù)據(jù)訪問(wèn)對(duì)象,在一個(gè)數(shù)據(jù)訪問(wèn)對(duì)象中我們完成對(duì)一個(gè)具體的數(shù)據(jù)庫(kù)實(shí)體的增,刪,改,查等操作。具體來(lái)說(shuō)就是我們寫出SQL語(yǔ)句,再把SQL語(yǔ)句所需要的參數(shù)一起傳遞給下層的數(shù)據(jù)庫(kù)操作模塊執(zhí)行。與DAO模塊同級(jí)的模塊還有Model,安全和工具模塊。Model在Java中還有另外一個(gè)稱呼叫做JavaBean,它的作用是用來(lái)封裝數(shù)據(jù)庫(kù)實(shí)體的數(shù)據(jù)。當(dāng)我們從數(shù)據(jù)庫(kù)中查詢出一組數(shù)據(jù)時(shí),這些數(shù)據(jù)我們就可以封裝到一個(gè)Model中,這樣在使用中也十分地方便,體現(xiàn)了面向?qū)ο蟪绦蛟O(shè)計(jì)中的封裝特性。安全模塊顧名思義就是封裝了一些和系統(tǒng)安全性有關(guān)的功能,比如說(shuō)數(shù)據(jù)加密模塊(舉例來(lái)說(shuō):對(duì)用戶密碼這種敏感數(shù)據(jù)在數(shù)據(jù)庫(kù)中一般是不能明文存儲(chǔ)的,要對(duì)密碼做一次Hash運(yùn)算。比較常用的算法是MD5加密,產(chǎn)生一個(gè)特定長(zhǎng)度的數(shù)據(jù)摘要后存儲(chǔ)在數(shù)據(jù)庫(kù)中)。工具類模塊中編寫了一些系統(tǒng)所需要用到的功能。比如說(shuō)在設(shè)計(jì)數(shù)據(jù)庫(kù)時(shí)我們常常會(huì)給一個(gè)表設(shè)計(jì)一個(gè)主鍵來(lái)唯一標(biāo)識(shí)一條記錄,由于主鍵在整個(gè)表中不能有重復(fù),因此我們就可以在程序中寫這樣一個(gè)工具類來(lái)專門產(chǎn)生這種唯一性的主鍵。再比如說(shuō)剛才我們提到的數(shù)據(jù)庫(kù)操作模塊是一個(gè)通用性要求非常高的程序模塊,需要能夠處理數(shù)據(jù)庫(kù)查詢到的任何形式和類型的數(shù)據(jù)。但是,有數(shù)據(jù)庫(kù)使用經(jīng)驗(yàn)的人都知道數(shù)據(jù)庫(kù)有時(shí)候查詢出的數(shù)據(jù)只有一組,有時(shí)候查詢出來(lái)的數(shù)據(jù)有多組(比如查詢一個(gè)班的所有學(xué)生信息,就會(huì)查出來(lái)多組數(shù)據(jù)),有時(shí)候查出來(lái)的數(shù)據(jù)就是一個(gè)整數(shù)值或浮點(diǎn)數(shù)值(比如查詢一張表有多少條記錄,或者是一個(gè)班的考試平均分),數(shù)據(jù)庫(kù)返回的數(shù)據(jù)形式可謂是千變?nèi)f化。我們不可能也沒(méi)必要在數(shù)據(jù)庫(kù)操作模塊中考慮到所有可能的數(shù)據(jù)形式。那么該如何確保這個(gè)模塊的通用性呢?解決方法就是定義接口,我們可以定義一個(gè)接口接收數(shù)據(jù)庫(kù)的返回?cái)?shù)據(jù)。當(dāng)數(shù)據(jù)庫(kù)完成查詢返回?cái)?shù)據(jù)時(shí)我們就不加處理地把數(shù)據(jù)傳遞給這個(gè)接口的方法,接著我們可以根據(jù)返回?cái)?shù)據(jù)的具體形式編寫類并且實(shí)現(xiàn)上述的接口,編程時(shí)可以根據(jù)數(shù)據(jù)庫(kù)返回?cái)?shù)據(jù)的具體形式動(dòng)態(tài)地傳入接口的具體實(shí)現(xiàn),這樣數(shù)據(jù)庫(kù)操作模塊的通用性就得到了保證。而這些接口的實(shí)現(xiàn)類也可以寫在工具類中,這些類可以是處理數(shù)據(jù)庫(kù)返回一組數(shù)據(jù)的情況,也可以是處理返回多組數(shù)據(jù)的情況。

寫到這里,數(shù)據(jù)持久層就寫完了。總的來(lái)說(shuō)數(shù)據(jù)持久層是Web系統(tǒng)中一個(gè)非常重要的模塊,工作量也是比較龐大的。這一層的程序必須非常健壯因?yàn)檫@一層是整個(gè)系統(tǒng)的基礎(chǔ),相當(dāng)于摩天大樓的地基,一旦在這一層出現(xiàn)大的Bug它的危害是全局性的。在開(kāi)始下一層——業(yè)務(wù)邏輯層的講述之前,我想說(shuō)一下業(yè)務(wù)邏輯層和數(shù)據(jù)持久層之間的這N多個(gè)接口。我們?cè)诔绦蛟O(shè)計(jì)時(shí)經(jīng)常聽(tīng)到一句話就是我們的程序要“高內(nèi)聚,低耦合”。在大型程序的開(kāi)發(fā)中這是必須要滿足的一個(gè)要求。所謂“高內(nèi)聚”就是要求一個(gè)類或函數(shù)的功能要相對(duì)單一,一個(gè)類或者函數(shù)最好只解決一件事或?qū)崿F(xiàn)一個(gè)單一的邏輯,而不要在一個(gè)類或函數(shù)中實(shí)現(xiàn)太多功能,因?yàn)檫@會(huì)導(dǎo)致程序的臃腫,界限不明和難以維護(hù)。從系統(tǒng)的角度講,相同或相似的功能最好在一個(gè)模塊中完成,而不要分散到多個(gè)模塊中,不同的模塊間不要有邏輯和功能上的重疊?!暗婉詈稀笔轻槍?duì)層與層來(lái)說(shuō)的。大型程序一般會(huì)對(duì)程序進(jìn)行分層,根據(jù)距離用戶的遠(yuǎn)近分為多層,在此可以參照TCP/IP協(xié)議體系的分層來(lái)理解,即所謂下層為上層提供服務(wù),層與層之間最好不要有過(guò)多的聯(lián)系,這樣一旦一層的程序出現(xiàn)些許紊亂也不至于導(dǎo)致連鎖反應(yīng),更重要的是層與層之間的低耦合性可以極大地提高發(fā)開(kāi)效率。拿我們的Web系統(tǒng)舉例,數(shù)據(jù)持久層為上面的業(yè)務(wù)邏輯層提供服務(wù),那么業(yè)務(wù)邏輯層沒(méi)必要和數(shù)據(jù)持久層發(fā)生什么直接的聯(lián)系。業(yè)務(wù)邏輯層只用告訴數(shù)據(jù)持久層我需要一些什么樣的服務(wù)(兩層之間那N個(gè)接口的作用就是用來(lái)說(shuō)明業(yè)務(wù)邏輯層需要什么樣的服務(wù)),數(shù)據(jù)持久層根據(jù)這些聲明的系統(tǒng)服務(wù)具體去實(shí)現(xiàn)就好了。這樣如果我們的程序面臨重構(gòu)或者面臨多組人同時(shí)開(kāi)發(fā),數(shù)據(jù)持久層的編寫人員只用根據(jù)業(yè)務(wù)邏輯層的服務(wù)需求具體去實(shí)現(xiàn)就好了而不用關(guān)心過(guò)多。而實(shí)現(xiàn)這種“低耦合”的最佳實(shí)現(xiàn)方法方法就是使用接口,針對(duì)不同的服務(wù)編寫不一樣的接口。DAO模塊中的不同數(shù)據(jù)訪問(wèn)對(duì)象根據(jù)自己操作實(shí)體的不同情況來(lái)選擇實(shí)現(xiàn)不同的接口來(lái)實(shí)現(xiàn)(在系統(tǒng)的數(shù)據(jù)庫(kù)中可能有許多種不同種類的實(shí)體,與不同類實(shí)體相關(guān)的操作也會(huì)截然不同。比如說(shuō)數(shù)據(jù)庫(kù)中的用戶實(shí)體和其他普通的數(shù)據(jù)實(shí)體在操作上就大不一樣。普通的數(shù)據(jù)實(shí)體可能更多的是批量或分頁(yè)查找,而用戶實(shí)體常常是需要判斷一個(gè)用戶是否存在或需要精準(zhǔn)地查詢到一個(gè)特定的用戶。那么針對(duì)不同類的數(shù)據(jù)庫(kù)實(shí)體, 就可以定義不同的接口來(lái)適應(yīng))。

業(yè)務(wù)邏輯層

業(yè)務(wù)邏輯層顧名思義就是處理業(yè)務(wù)邏輯的地方,什么是業(yè)務(wù)邏輯?比方說(shuō)我們?cè)L問(wèn)一個(gè)購(gòu)物網(wǎng)站當(dāng)我們決定購(gòu)買一件商品并點(diǎn)擊購(gòu)買按鈕時(shí)對(duì)服務(wù)器來(lái)說(shuō)就面臨一個(gè)業(yè)務(wù)邏輯,一個(gè)購(gòu)買操作可能細(xì)分下來(lái)包括用戶驗(yàn)證,查詢商品庫(kù)存是否充足,生成訂單,支付等等。這些子操作構(gòu)成了購(gòu)買這個(gè)需求的業(yè)務(wù)邏輯。這些處理業(yè)務(wù)邏輯的程序就存在于我們的業(yè)務(wù)邏輯層中。無(wú)論多么復(fù)雜的業(yè)務(wù)邏輯最終都將會(huì)反映到對(duì)數(shù)據(jù)庫(kù)的增刪改查上,因此在業(yè)務(wù)邏輯層中我們將會(huì)調(diào)用剛才提到的業(yè)務(wù)邏輯與數(shù)據(jù)持久層中間的那些接口來(lái)實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的操作。

表示層

表示層是整個(gè)后端程序中距離用戶最近的程序,它負(fù)責(zé)為用戶展示界面。比如說(shuō)我們要登錄系統(tǒng),當(dāng)我們填入用戶名和密碼并且點(diǎn)擊登錄按鈕后,表示層就會(huì)驗(yàn)證你的用戶名和密碼是否匹配,如果匹配就給用戶展示一個(gè)登陸成功的界面,反之則會(huì)給用戶展示一個(gè)失敗的界面(通常情況下HTML界面和JSP頁(yè)面也算作表示層的東西)。一句話,表示層決定用戶將看到什么樣的界面。但是看到這里你可能會(huì)發(fā)現(xiàn)表示層和業(yè)務(wù)邏輯層在功能上有重疊,的確是這樣。但也不是都重復(fù),比如說(shuō)業(yè)務(wù)邏輯層中的處理用戶上傳文件的模塊就是一個(gè)單純的業(yè)務(wù)邏輯層的模塊而與表示層無(wú)關(guān)。

前端

J2EE有自己一套獨(dú)立的前端體系——JSP,這是一套比較老的前端技術(shù)了,本質(zhì)上說(shuō)也是一種Servlet。開(kāi)發(fā)起來(lái)比較簡(jiǎn)單,有豐富的標(biāo)簽和EL表達(dá)式,還可以開(kāi)發(fā)自己的標(biāo)簽庫(kù),十分靈活。不過(guò)目前在H5頁(yè)面比較火熱的情況下,前端頁(yè)面推薦多使用HTML+JavaScript,頁(yè)面靈活豐富。使用Ajax來(lái)加載數(shù)據(jù)(傳送門:腳本化HTTP初探(一)),這樣系統(tǒng)反應(yīng)更快,用戶體驗(yàn)會(huì)好一些。

其它

寫到這里,服務(wù)器端主要的架構(gòu)就說(shuō)完了。總的來(lái)說(shuō)整個(gè)系統(tǒng)遵循“高內(nèi)聚,低耦合”的設(shè)計(jì)原則,代碼編寫時(shí)要多多體現(xiàn)面向?qū)ο蟪绦蛟O(shè)計(jì)的三大基本特性。最后再說(shuō)兩個(gè)J2EE的小地方,一個(gè)是過(guò)濾器一個(gè)是監(jiān)視器。

過(guò)濾器是整個(gè)系統(tǒng)流量的入口和出口,就是說(shuō)我們給服務(wù)器發(fā)送的一切請(qǐng)求,服務(wù)器對(duì)我們?yōu)g覽器做出的一切回應(yīng)都將會(huì)先通過(guò)過(guò)濾器才會(huì)達(dá)到我們的服務(wù)器或是我們的瀏覽器,在過(guò)濾器中我們可以看到這些請(qǐng)求或回應(yīng)的一切參數(shù)和數(shù)據(jù),并且可以做任意地更改,這是一個(gè)激動(dòng)人心的特性,我們可以利用這個(gè)特性做很多事兒。比如說(shuō),我們可以用過(guò)濾器攔截敏感詞匯,過(guò)濾關(guān)鍵字,可以對(duì)用戶提交的信息做轉(zhuǎn)義輸出(有些無(wú)良用戶會(huì)提交一些可執(zhí)行代碼給服務(wù)器,有時(shí)候可能導(dǎo)致服務(wù)器異常關(guān)機(jī),因此必須要對(duì)用戶提交的數(shù)據(jù)做轉(zhuǎn)義),最重要的一個(gè)應(yīng)用就是在過(guò)濾器中解決中文亂碼問(wèn)題,這個(gè)問(wèn)題是由于針對(duì)當(dāng)今的Unicode字符流行著許許多多的編碼方式而產(chǎn)生的。拿漢字舉例,常用的編碼方式就有UTF-8,GB2312,和ISO8859-1等。如果客戶機(jī)和服務(wù)器所用的編碼方式不一樣,就會(huì)導(dǎo)致出現(xiàn)中文亂碼。解決思路就是在過(guò)濾器中我們?cè)O(shè)置HTTP頭中的Content-type字段,強(qiáng)制客戶端的編碼碼表,并且針對(duì)URL進(jìn)行編碼。這樣就能很好地解決中文的亂碼問(wèn)題。

另一個(gè)J2EE特性就是監(jiān)視器,說(shuō)監(jiān)視器之前就要說(shuō)J2EE中五個(gè)十分重要內(nèi)置對(duì)象,分別是Context對(duì)象,Session對(duì)象,Request對(duì)象,Response對(duì)象和Cookie對(duì)象。這五個(gè)對(duì)象是J2EE中極端重要的對(duì)象,接下來(lái)我們分別簡(jiǎn)單地介紹一下。Context對(duì)象是服務(wù)器中的一個(gè)單例對(duì)象,就是說(shuō)在整個(gè)服務(wù)器中Context對(duì)象有且僅有一個(gè),不存在任何拷貝。服務(wù)器中的任何程序都可以訪問(wèn)Context對(duì)象所在的內(nèi)存,它的生命周期與服務(wù)器的生存周期是相同的,也就是說(shuō)服務(wù)器啟動(dòng)Context對(duì)象就存在,只有當(dāng)服務(wù)器停止時(shí)Context對(duì)象才被銷毀。Context對(duì)象中封裝一些全局性的數(shù)據(jù),比如說(shuō)當(dāng)前在線人數(shù)啊,所有已經(jīng)登錄的用戶啊這些可能很多地方都要用到的數(shù)據(jù)。Session對(duì)象是用來(lái)唯一標(biāo)識(shí)用戶的,我們所熟知的登錄操作就是用Session做的。Session對(duì)象是通過(guò)Cookie的一個(gè)JSESSIONID字段來(lái)唯一標(biāo)識(shí)一個(gè)用戶,具體來(lái)說(shuō)就是Session會(huì)回寫一個(gè)Cookie給瀏覽器,這個(gè)Cookie中有一個(gè)字段JSESSIONID,它的值是一串很長(zhǎng)的字符串,不同用戶的JSESSIONID都不同,服務(wù)器中的Session對(duì)象根據(jù)不同客戶機(jī)的JSESSIONID字段就可以唯一標(biāo)識(shí)一個(gè)用戶。正是由于Session對(duì)象這種標(biāo)識(shí)用戶的特性,我們可以在Session對(duì)象中封裝與具體用戶有關(guān)的信息,比如說(shuō)一個(gè)用戶的姓名,ID等等信息。它的生命周期默認(rèn)是30分鐘,就是說(shuō)一個(gè)Session對(duì)象被創(chuàng)建出來(lái)如果30分鐘內(nèi)沒(méi)有使用過(guò),那么這個(gè)Session對(duì)象就會(huì)被自動(dòng)銷毀。有時(shí)候我們登錄一個(gè)賬號(hào)一段時(shí)間不去操作,再去用的時(shí)候就會(huì)被提示沒(méi)有登錄原因就在于此。Request和Response對(duì)象是服務(wù)器中封裝請(qǐng)求和回應(yīng)信息的對(duì)象,通過(guò)這兩個(gè)對(duì)象可以獲得請(qǐng)求的參數(shù),請(qǐng)求的方式等等諸多細(xì)節(jié),這兩個(gè)對(duì)象的生命周期很短通常只有一個(gè)請(qǐng)求回應(yīng)周期,也就是說(shuō)當(dāng)客戶機(jī)給服務(wù)器發(fā)送一個(gè)請(qǐng)求,服務(wù)器回應(yīng)之后這兩個(gè)對(duì)象就被銷毀,內(nèi)存就被回收了。而至于Cookie對(duì)象它與瀏覽器和Request,Response對(duì)象都有關(guān),是一個(gè)特殊的HTTP頭部字段,在瀏覽器中也有存儲(chǔ),在這里就不細(xì)說(shuō)了。而我們要說(shuō)的監(jiān)視器就是用來(lái)針對(duì)Context對(duì)象,Session對(duì)象,Request對(duì)象和Response對(duì)象。一旦我們實(shí)現(xiàn)了監(jiān)視器,我們就可以在這四個(gè)對(duì)象創(chuàng)建,銷毀,寫入數(shù)據(jù)時(shí)做點(diǎn)事情。最常見(jiàn)的應(yīng)用就是在線人數(shù)統(tǒng)計(jì),我們之前提到過(guò)登錄本質(zhì)上就是一個(gè)Session被創(chuàng)建的過(guò)程,那么我們就可以寫一個(gè)針對(duì)Session對(duì)象的監(jiān)聽(tīng)器,一旦一個(gè)Session創(chuàng)建則登陸人數(shù)就加一。

以上就是全篇的內(nèi)容啦,希望共同學(xué)習(xí)共同進(jìn)步!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容