這篇文章試圖從J2EE客戶端的角度出發(fā)來介紹J2EE體系。將介紹J2EE的客戶端如何對EJB進行訪問。J2EE的客戶端分類。最后重點分析J2EE中兩種相似的客戶端Stand alone Client與J2EE Application Client。并會給出針對同一個Stateless Session Bean的這兩種不同客戶端的實現(xiàn)實例來具體說明它們的異同。 本文的所有實例都基于SUN的J2EE SDK進行發(fā)布。附錄中也會對SUN的這個非常方便我們學(xué)習(xí)J2EE的開發(fā)工具集進行介紹。 J2EE的客戶端,簡單的說就是所有針對EJB而言都處于客戶調(diào)用邏輯的組件與程序。因為J2EE結(jié)構(gòu)的復(fù)雜性,J2EE客戶端也比較多,一般分為以下五種。Stand Alone Client,J2EE Application Client,JSP,Servlets,其它Enterprise JavaBeans(處于客戶邏輯的EJB)。 這其中,大家對JSP與Servlets可能是比較熟悉的,因為現(xiàn)在基于J2EE的應(yīng)用開發(fā)大部分是Broswer/Server模式,所以它們也是最常用的J2EE的客戶端。而EJB本身起到客戶端作用,我們也會經(jīng)常碰到,比如在Session Bean中調(diào)用Entity Bean中的商業(yè)方法,那么Session Bean 就是這個Entity Bean的客戶端。 談到J2EE就不能不提到EJB。EJB是J2EE結(jié)構(gòu)的核心,我們在它里面實現(xiàn)商業(yè)邏輯,而由實現(xiàn)J2EE結(jié)構(gòu)的服務(wù)平臺提供商為我們提供J2EE Server、EJB Container、Web Container,從而為我們提供諸如安全控制、事務(wù)處理、客戶連接、以及數(shù)據(jù)庫訪問這些服務(wù)。這樣通過對整個體系劃分出不同的角色(如應(yīng)用開發(fā)者,J2EE服務(wù)器提供商等等),讓我們這些開發(fā)者可以專心于商業(yè)邏輯的實現(xiàn),并能最大限度的實現(xiàn)代碼的可復(fù)用性。 在EJB1.1規(guī)范中有兩種EJB,一種是Session Bean另一種是Entity Bean。這兩種EJB也是我們最常用到的。不論是Session Bean 還是Entity Bean它們在實現(xiàn)上都是由三部分組成。首先是Remote Home Interface,在這個遠程接口中定義的是可由客戶端調(diào)用的創(chuàng)建、查找(對Entity Bean而言)EJB的方法。然后是Remote Interface,這個遠程接口中定義的是可供客戶端訪問的商業(yè)方法。最后是Bean Class,這個類對客戶端而言是不可訪問的,在這個類中我們要具體實現(xiàn)相應(yīng)的商業(yè)方法,以及一些供EJB Container調(diào)用的方法。對Session Bean 與Entity Bean,以及對Entity Bean 中的bmp模式以及cmp模式而言,這個類會有很大的不同。但這不是這篇文章要重點介紹的,你只要記住對J2EE的客戶端,能看到的只是Remote Interface與Remote Home Interface這兩個接口而已。下面讓我們看看客戶端是如何具體完成對EJB的訪問的。
不論是那種J2EE的客戶端,它要調(diào)用一個EJB的相應(yīng)商業(yè)方法都要經(jīng)過以下這三步: 1、 通過JNDI定位EJB的Remote Home Interface 創(chuàng)建JNDI名稱環(huán)境,通過在發(fā)布時你給EJB定義的JNDI名稱找到該EJB的Remote Home Interface。 2、 創(chuàng)建EJB的實例,得到Remote Interface 調(diào)用上一步得到的Remote Home Interface中的create()方法,EJB Container會創(chuàng)建相應(yīng)EJB的實例。而你得到的就是一個定義了EJB要實現(xiàn)的商業(yè)方法的Remote Interface。(EJB Container創(chuàng)建EJB實例的基本過程如下:客戶端調(diào)用create()方法-'EJB Container實例化相應(yīng)的EJB Bean Class'EJB Container調(diào)用Bean Class中的ejbCreate方法'最后返回給我們的是EJB的Remote Interface) 3、 調(diào)用Remote Interface中的商業(yè)方法 客戶端調(diào)用上一步創(chuàng)建的Remote Interface中的商業(yè)方法,EJB Container就會調(diào)用相應(yīng)Bean Class實例中的相應(yīng)方法。 下面讓我們通過具體的代碼來說明這個過程。首先我們先來創(chuàng)建一個Stateless Session Bean。這個Session Bean實現(xiàn)的功能很簡單,在其中的商業(yè)方法只有一個sayHello方法,打印一句"Hello World:"。如我上邊所介紹的這個EJB共有三個部分,它們的源代碼如下所示: 包括create()方法的Remote Home Interface接口:
定義商業(yè)方法的Remote Interface接口:
實現(xiàn)商業(yè)方法的Bean Class :
有了具體的EJB后,我們就可以看看在J2EE客戶端是如何具體完成上邊三步的。首先,我們通過JNDI得到HelloWorldHome接口,這個過程又分為以下幾步:
在我們得到了EJB的Remote Home Interface后,我們通過其中的create()方法創(chuàng)建一個EJB實例,并得到Remote Interface。代碼如下: 現(xiàn)在我們就可以通過上一步得到的Remote Interface來調(diào)用我們想調(diào)用的商業(yè)方法。這里我們的EJB只實現(xiàn)了一個sayHello()方法。用如下的代碼完成對它的調(diào)用: 所有的客戶端訪問EJB都是要經(jīng)過以上這些步驟。Servlets一般在它的init()方法中完成創(chuàng)建EJB實例的步驟。而JSP訪問EJB,最好都通過Java Beans來實現(xiàn),所以一般在相應(yīng)Java Bean的初始化方法中完成創(chuàng)建EJB的步驟。當然你也可以根據(jù)自己的需要在任意地點完成這些步驟。 這篇文章試圖從客戶端的角度來向大家介紹J2EE結(jié)構(gòu),而不是只對客戶端進行介紹。所以在這里還有一些其他的信息希望大家能了解一下。在EJB2.0規(guī)范中,有一些新的情況出現(xiàn)了,可以對EJB進行本地訪問(Local Access)。實現(xiàn)了本地訪問的EJB像實現(xiàn)了遠程訪問的EJB一樣有兩個接口供客戶端訪問。一個是Local Interface它像Remote Interface一樣定義要實現(xiàn)的商業(yè)邏輯。一個是Local Home Interface,它提供創(chuàng)建EJB以及查找(對Entity Bean而言)方法,就像Remote Home Interface一樣。這兩個Local Interface是供客戶端訪問而用,而對EJB的實現(xiàn)仍然在Bean Class中。對客戶端而言,如果它要訪問一個只有本地接口的EJB,那么它必須要和這個EJB在同一個java虛擬機中。而對一個實現(xiàn)遠程接口的EJB,當然沒有這樣的限制。本地訪問會提高系統(tǒng)性能,而且在一些場和你必須要讓EJB實現(xiàn)本地訪問(如container-managed relationship中目標端的Entity Bean,詳情請參考EJB2.0規(guī)范。一般只是在Entity Bean中實現(xiàn)本地訪問接口)。 這樣設(shè)計一個EJB時你要考慮是實現(xiàn)遠程還是本地訪問。如果你所有的組件如EJB、WEB、J2EE Client等只是發(fā)布于同一臺機器上,那么你就可以選擇為EJB實現(xiàn)本地接口(當然還有一些必須實現(xiàn)本地接口的情況)。如果你要考慮分布式的情況,那么實現(xiàn)遠程訪問接口是你唯一的選擇。如果你的EJB使用本地訪問的話,對客戶端就有了一些新的變化??蛻舳嗽L問實現(xiàn)了本地接口EJB的流程和上面介紹的訪問實現(xiàn)遠程接口EJB的過程基本一樣。但在通過EJB的JNDI名稱得到EJB的對象后,對其造型成相應(yīng)EJB的Local Home接口時,不需要再使用javax.rmi.PortableRemoteObject中的方法,而是直接用相應(yīng)對象類型造型。假設(shè)我們上邊的EJB實現(xiàn)的是本地訪問接口,那么相應(yīng)客戶端訪問代碼如下:
還有在EJB2.0中出現(xiàn)了一種新的EJB:Message-Driven Bean。這種新的EJB類型和其他兩種有很大不同。首先,它不像其它兩種EJB那樣有自己的供客戶端調(diào)用的Remote或者Local Interface,它只有一個Bean Class。而且客戶端也無法定位及調(diào)用Message-Driven Bean中的方法。對客戶端而言它是不可見的。 下面詳細介紹一下J2EE中的兩種客戶端,Stand alone Client與J2EE Application Client。
這種客戶端就如它的名字一樣,它獨立于J2EE,不是J2EE的組件。它一般用于測試我們開發(fā)的EJB。下面是一個具體的例子,它訪問的EJB是上邊的那個Stateless Session Bean。
打開一個dos窗口,使用如下的指令編譯我們的代碼(請根據(jù)自己的環(huán)境對里面的參數(shù)作相應(yīng)調(diào)整): 編譯完成后在運行這個例子之前,要在我們的J2EE 服務(wù)器上發(fā)布我們所實現(xiàn)的EJB。這里我使用的J2EE服務(wù)器是J2EE SDK 1.3,有關(guān)它的介紹請見本文的附錄1--J2EE SDK1.3介紹。如何在它上邊發(fā)布HelloWorld EJB的詳細步驟請見附錄2--發(fā)布HelloWorld Staless Session Bean。 在服務(wù)器已經(jīng)啟動,EJB已經(jīng)發(fā)布的情況下,讓我們來運行一下上邊的例子,使用如下的命令運行: 這樣你就可以在J2EE Server控制臺上看到我們的MyStandAloneClient調(diào)用sayHello方法所打印出來的"Hello :)"(使用j2ee -verbose啟動服務(wù)器)。
它和Stand alone Client很像,也是一個java application,但不同的是這種客戶端是J2EE組件的一種。所以要想使用這種客戶端,你就要用相應(yīng)J2EE服務(wù)器的應(yīng)用發(fā)布工具將它發(fā)布到服務(wù)器上。因為它是J2EE的組件,它與Stand alone Client最大不同在于它可以使用J2EE提供的服務(wù)。比如它可以由J2EE統(tǒng)一進行安全認證,在你運行J2EE Application Client時系統(tǒng)會自動彈出一個認證窗口,你輸入J2EE服務(wù)器上許可的用戶名和密碼后才能運行這個程序,從而訪問J2EE Server上的EJB。它給我們開發(fā)帶來的好處是可想而知的。 還有在J2EE Application Client中,你可以通過為已有的EJB加入JNDI參考來用自己定義的JNDI名稱訪問EJB。例如在我的例子中是通過下面的代碼來得到EJB對象的: 大家也許記得在Stand alone Client例子中,我是通過"HelloWorld"JNDI名稱得到同樣的對象的。而這里卻是"ejb/hai"。用不同的JNDI名稱來訪問同一個EJB。這樣做的好處就是你可以隨意更改你的EJB的JNDI名稱,而J2EE Application Client程序代碼不需要有任何更改,只需要修改EJB參考中的對應(yīng)關(guān)系就可以了。這里是源代碼:
你會發(fā)現(xiàn)在代碼上除了上面提到的JNDI名稱不同外,沒有其他什么不同。但是我們不能像對Stand alone Client那樣,編譯完后就運行它,而要先創(chuàng)建一個J2EE Application Client組件,并把它加入到我們的應(yīng)用中。有關(guān)這個創(chuàng)建過程請參考文章附錄3--創(chuàng)建J2EE Application Client組件。 |
|
|
來自: fondofbeyond > 《我的圖書館》