本文面向的觀眾是對J2EE技巧有愛好的進門者。
Java語言
Java語言最早被稱為Oak,它是為了實現(xiàn)嵌進式的消費類電子產(chǎn)品利用而產(chǎn)生的,它的作者是James Gosling。Ed Frank, Patrick Naughton, Jonathan Payne, Chris Warth在隨后的幾年時間中為Java語言加進了大批的特征,并把Java語言的目標做了
一個重新的定位,定位于合適Internet的語言。
Java語言是一種多用處的語言、并發(fā)的語言、以類為基礎(chǔ),面向
對象的語言。它的設(shè)計盡可能的做到和把持系統(tǒng)是無關(guān)的,也就是Java所宣傳的那句話:“一次編寫,到處運行。”Java的設(shè)計參考了C和C++語言,因此熟悉C和C++的程序員對Java語言上手很快,而Java設(shè)計的原則是能夠利用Java語言快捷的編寫利用,所以我們可以創(chuàng)造,在Java語言中,并沒有那些C和C++中的復(fù)雜的機制。最明顯的就是C中被大批應(yīng)用的指針,由于它的隨便性,被Java以引用來代替了。而C++中的把持符重載、模板、泛型的特征也由于應(yīng)用比較復(fù)雜,Java也不予采用。但是目前Java仍然不斷的推出新的特征,以滿足利用的發(fā)展。例如在新推出的JDK1.4中,Java語言就能夠支撐Assertment機制和Perl語言中最有用的正則表達式機制。
Java語言重要由以下五種元素組成:標識符、要害字、文字、運算符和分隔符。這五種元素有著不同的語法含義和組成規(guī)矩,它們互相配合,共同完成Java語言的語意表達。
1:標識符。變量,類和
方法都需要必定的名稱,我們將這種名稱叫做標識符。
2:要害字。要害字是Java語言本身應(yīng)用的標識符,它有其特定的語法含義。所有的Java要害字將不能被用作標識符。
3:數(shù)據(jù)類型。Java有著不同的數(shù)據(jù)類型。比較值得一提的是字符串數(shù)據(jù)類型,字符串數(shù)據(jù)類型是用一對雙引號括起來的字符序列,字符串數(shù)據(jù)實際上是由String類所實現(xiàn),而不是C語言中所用的字符數(shù)組。每一個字符串數(shù)據(jù)將產(chǎn)生一個String類的新的實例,用戶不必對字符串與類這個概念產(chǎn)生關(guān)系而感到擔心,由于類的特征,你不必擔心如何往實現(xiàn)它們,它們會自己照顧好自己,需要闡明的是字符串在Java里作為類只是出于安全的考慮。
4:運算符。任何語言都有自己的運算符,Java語言也不例外,如+、-、*、/等都是運算符,運算符的作用是與必定的運算數(shù)據(jù)組成表達式來完成相應(yīng)的運算。對不同的數(shù)據(jù)類型,有著不同的運算符。
5:分隔符。分隔符用來使編譯器確認代碼在何處分隔?!?’‘:’都是Java語言的分隔符。
學習 Java 語言很簡略,畢竟 Java 語言也只包含五十多個要害詞(keyword)與幾十個算符(operator),再加上 Java 語法(syntax)也很簡略,所以一般人可以很快就學會 Java 語言。危險的是,很多人認為已經(jīng)完整掌控 Java 語言,但實在對于內(nèi)部的運作機制仍不能把握,這些盲點有時候會讓你無法完整掌控 Java 語言??朔@些盲點的方法是看「The Java Language Specification, 2nd Ed.」(沒有中文版)來徹底弄懂 Java 程序語言,并看「Inside the Java Virtual Machine, 2nd Ed.」來徹底把握 Java 虛擬機器的運作方法。學會了語言,并不代表就可以設(shè)計出好的對象導(dǎo)向系統(tǒng)架構(gòu)。想要成為對象導(dǎo)向的專家,往往需要:(1) 多看相干的書,特別是 Design Pattern 和 Refactoring 的書。(2) 多觀摩別人的程序(例如 Java API 的 design 與 implementation)(3) 多寫程序。學會 Java 語言之后,還需要學會一些 API 才干寫出有用的程序。Java 的 API 非常多,必須方案好一個學習路徑,才不會在浩瀚的 API 大海中迷失。必備的 API 包含了:IO、New IO、Collection Framework、Network、RMI、JAXP... 等。至于其它的 API,就看你的需求而定,大致上分成:
* GUI 類:JavaBean -> Swing -> JavaHelp -> Java2D -> Image IO -> JAI -> Java 3D ...
* Enterprise 類:JDBC -> JDO -> Servlet -> JSP -> EJB -> JMS -> JTA/JTS...
* J2ME 類(這一類不是我的專長,無法供給學習次序建議)
Java語言通常都是根據(jù)Java虛擬機規(guī)范(The Java Virtual Machine Specification)中的定義,編譯為字節(jié)碼指令集和二進制格式。因此我們接下來就討論Java虛擬機(JVM)
JVM
我們已經(jīng)談過Java語言的語法類似于C和C++,但是摒棄了C和C++中復(fù)雜、困惑和不安全的特征。Java語言最早是用來構(gòu)建消費類網(wǎng)絡(luò)設(shè)備的軟件的,因此它要支撐多主機的架構(gòu),并請求能夠供給安全的軟件組件。為了滿足這些需求,編譯好的代碼就必須能夠通過網(wǎng)絡(luò)來流傳,能夠在任何客戶端上運行,同時還要保證客戶端是足夠安全的。
Java虛擬機是Java和Java 2 平臺的基石。它能夠保證Java語言和硬件、把持系統(tǒng)無關(guān),保證編譯后的代碼最小,并掩護用戶不受惡意程序的攻擊。Java虛擬機到底是什么呢。實在它就是一臺不實際存在的盤算機。和真實的盤算機類似,它也有自己的指令集,并可以在運行環(huán)境中分配內(nèi)存區(qū)域。應(yīng)用虛擬機機制來實現(xiàn)編程語言并不是Java的創(chuàng)舉,這已經(jīng)是非常廣泛的做法了,最著名的許你就莫過于UCSD Pascal的P-Code機。
只要瀏覽器檢測到目前所處理的Web文件內(nèi)容含有一個Java Applet,瀏覽器將會為這個Java小程序另外開一個JVM,履行這個Java利用小程序。在JVM中履行的Java小程序可以得到充分安全的掩護。如同我們上面所說,JVM是一個自給自足的作業(yè)環(huán)境,就像是一臺獨立的盤算機一樣。例如,在JVM運作的Applet,無法存取主機把持系統(tǒng)。優(yōu)點是:
1. 系統(tǒng)中立。Java利用程序可以在任何JVM中運作,不論該系統(tǒng)應(yīng)用何種硬件、軟件。
2. 安全。正因JVM跟把持系統(tǒng)沒有任何接觸,Java程序很難侵害到其它檔案或利用程序。
毛病是,由于在JVM運作的程序獨立在把持系統(tǒng)之外,也就無法享受把持系統(tǒng)各項特別功效。
Java技巧之所以在今天得到了如此廣闊的利用,其中它的安全性是不能不提的。不同于其它技巧(例如Microsoft的ActiveX)中安全性作為附加設(shè)計和補丁,Java從設(shè)計之初便考慮到了安全性。因此Java的安全性是在語言層次實現(xiàn)的。Java的安全性由下列三個方面保證:
1、 語言特征(包含數(shù)組的邊界檢查、類型轉(zhuǎn)換、取消指針型變量)。
2、 資源訪問把持(包含本地文件系統(tǒng)訪問、Socket連接訪問)。
3、 代碼數(shù)字簽名(通過數(shù)字簽名來確認代碼源以及代碼是否完整)。
Java的源代碼是先編譯成為一種字節(jié)碼的中間代碼,存放這種代碼的文件就是.class的文件。真正履行的時候是將class文件裝載到JVM(虛擬機)中,然后由JVM解釋履行的。所以數(shù)組的高低界檢查及正當?shù)念愋娃D(zhuǎn)換是通過JVM得到保證的。Java通過一個類裝載器類(ClassLoader)將虛擬機代碼文件(即class文件)裝載到JVM中,當完成裝載后,一個被稱做安全治理器(SecurityManager)的類開端運行,例如當一個Applet的class文件被缺省的類裝載器裝載到JVM中后,JVM會立即為它裝載一個SecurityManager的子類AppletSecurity,由這個治理器來驗證把持。代碼的所有動作(例如文件讀寫)都要先經(jīng)過驗證,只有被該安全治理器吸收的動作才干完成,否則就會拋出SecurityException異常。
對于JDK1.0,權(quán)限被籠統(tǒng)的劃分為兩大塊。一是擁有所有的權(quán)限,一個是僅擁有"沙箱"(sandBox)權(quán)限,這也是普通的Applet所擁有的權(quán)限。這時本地文件讀寫或是與源主機(Orignal Server)以外的主機連接都是被禁止的。這種劃分的最大標題就是缺乏機動性。例如我們??匆粋€Applet在用戶信任的情況下能夠?qū)Ρ镜匚募到y(tǒng)的某個目錄進行讀寫,但并不要通過Socket與其它主機連接。這是JDK1.0的權(quán)限劃分就不能達到請求。JDK1.1后改良了權(quán)限的劃分,引進了權(quán)限集(PermissionSet)的概念。
由于我們的文章并不是討論JVM,因此,我們只是對JVM做一個簡略的先容。假如需要具體懂得的,可以參考『The JavaTM TMVirtual Machine Specification』。
客觀的看待Java 相對于其他編程語音,Java有一個無庸置疑的優(yōu)點:用戶以及編譯器第一次不必懂得天生可履行代碼的特定CPU細節(jié)。Java引進了一個編譯代碼中間層,叫做字節(jié)代碼,并應(yīng)用一個虛擬抽象的機器,而不是一個真實的機器。當Java編譯器結(jié)束了一個源文件的編譯后,你所得到的不是可以立即在一個給定平臺上運行的代碼,而是可以在任何真實的平臺上運行的字節(jié)代碼,唯一的條件就是這個平臺要懂得和支撐Java。這些發(fā)展包含著一個文化的變更。作為一個開發(fā)職員,你只需要斷定Java虛擬機(JVM)供給的抽象層,不同的OS銷售商負責履行代碼層,從而將中立于平臺的字節(jié)代碼映射到主機平臺的機構(gòu)中。在這種情況下,Java似乎是同一散布式盤算機世界的領(lǐng)袖候選人了?!熬帉懸淮?,永遠運行”(并且無論在哪里)就成為Java誘人但卻真實的口號。
但我們平心而論,Java的跨平臺并不是一個非常誘人的特征?跨平臺理論的發(fā)展很好地證實了這一點。我們看到,將Java代碼從一個平臺移植到另一個平臺?Java這個語言最重要和最受吹捧的特點?并不象宣傳的那樣輕易。任何Java平臺都有其自己的虛擬機,它可以懂得通用的字節(jié)代碼,并且及時地將其編譯為本地代碼。抵觸由此產(chǎn)生,不同虛擬機的履行也很不雷同,這一點足以使代碼的移植比預(yù)期耗費多得多的時間,而且基礎(chǔ)上不是主動的。在企業(yè)用戶的角度上來說,也很少會有企業(yè)會頻繁的調(diào)換平臺,因此這個特征是否能夠帶來高價值是很難評價的。
那么,Java模型的利益在哪里呢?首先,Java是一種先進的、面向?qū)ο蟮恼Z言,包含了預(yù)防常見毛病的內(nèi)置功效,并在僅僅一兩個對象中攜帶了很多經(jīng)常需要用到的功效。與C++相比,Java更易于讀寫,不輕易出錯,而且更加雅觀,但是它速度較慢也不太機動。想實現(xiàn)在任何軟件和硬件平臺上都可虛擬移植,Java盡可能少地應(yīng)用了公分母模型,也就是說放棄了將每個平臺開發(fā)到極限的能力。第二,虛擬機的概念本身就是可移植和可共用的,因此對于散布式環(huán)境來說是理想的。Java對于為非Windows平臺開發(fā)代碼是最好的語言。
那么對于Windows平臺來說,Java又怎么樣呢?讓Java適應(yīng)Windows是不可能的,這是由于Sun的允許束縛標題。但是Java實在是太吸引人了,Microsoft比誰都能更明確這一點。Microsoft在以前推出的Visual J++證實了這一點,但是惋惜的是,Microsoft又犯了霸權(quán)的老弊病,Visual J++并不好用。因此,Microsoft又一次采用了“拿來主義”的伎倆,很好地利用了Java 的眾多特征,隆重推出了Windows平臺的新銳力量,它就是相當簡略但十分壯大的面向?qū)ο蟮腃#編程語言。C#超過了C++,它天生就包含了.NET框架類庫中的所有類,并使語法簡略化。說到這里已經(jīng)有一些離題了,不過Java也不是說在Windows平臺上就不能夠應(yīng)用,JDK和大部分的IDE都支撐Windows平臺。
Java技巧的架構(gòu)--J2ME、J2SE和J2EE
通常我們以 JDK(Sun 所開發(fā)的一套 Java 開發(fā)工具)的版本來定義 Java 的版本。JDK 1.0 版于 1996 年初公然,JDK 1.1 版于 1997 年初公然,JDK 1.2 版于 1998 年底公然。基于市場行銷的考量,Sun 在 JDK 1.2 版公然后旋即將 Java 改名為「Java 2」,將 JDK 改名為「Java 2 Software Development Kit(以下簡稱 J2SDK)」。J2SDK(原稱 JDK)1.3 于 2000 年 4 月公然,此版本仍稱做「Java 2」。目前 J2SDK 1.4 也已經(jīng)公然了,大家可以到Sun的官方Java站點上查閱到大批的JDK1.4的信息。
Java 技巧根據(jù)硬件平臺與實用環(huán)境的差別,分成幾個分支。JDK 1.1 的時代,實用于一般消費性電子產(chǎn)品等,嵌進式系統(tǒng)的 Java 平臺是 PersonalJava 與 EmbeddedJava,此二者并無明確的界限,大致上來說,運算資源、內(nèi)存、以及顯示裝置比較豐富者,應(yīng)用 PersonalJava,例如 Set-Top Box、視訊電話 ... 等;反之,資源較有限者應(yīng)用 EmbeddedJava,例如召喚器、舉動電話 ... 等。除了 PC 應(yīng)用的 Java 平臺、IA 應(yīng)用的 PersonalJava 與 EmbeddedJava 平臺之外,JavaCard 也是一個 Java 平臺,應(yīng)用于 Smart Card(IC Card)上。
Java 2 涌現(xiàn)后,顛覆了先前的 PersonalJava 與 EmeddedJava 的分法,改分成 Java 2 Platform Enterprise Edition(簡稱 J2EE)、Java 2 Platform Standard Edition(簡稱 J2SE)、Java 2 Platform Micro Edition(簡稱 J2ME)。J2EE 實用于服務(wù)器,目前已經(jīng)成為企業(yè)運算、電子商務(wù)等領(lǐng)域中相當熱門的技巧;J2SE 實用于一般的盤算機;J2ME 實用于消費性電子產(chǎn)品。除了這三者之外,JavaCard 依然是獨立的一套標準。
目前,Java技巧的架構(gòu)包含三個方面:
J2EE(Java 2 Platform Enterprise Edition )?企業(yè)版 (J2EE) 是為面向以企業(yè)為環(huán)境而開發(fā)利用程序的解決方案。
J2SE(Java 2 Platform Stand Edition)?標準版 (J2SE) 為桌面開發(fā)和低端商務(wù)利用供給了可行的解決方案。
J2ME(Java 2 Platform Micro Edition )?小型版(J2ME)是致力于消費產(chǎn)品和嵌進式設(shè)備的最佳解決方案
J2EE
J2EE已經(jīng)成為開發(fā)商創(chuàng)立電子商務(wù)利用的事實標準。正是熟悉到J2EE平臺作為一種可擴大的、全功效的平臺,可以將要害的企業(yè)利用擴大到任何Web瀏覽器上并可合適多種不同的Internet數(shù)據(jù)流、可連接到幾乎任何一種傳統(tǒng)數(shù)據(jù)庫和解決方案、使企業(yè)經(jīng)理根據(jù)多家企業(yè)所供給的產(chǎn)品和技巧開發(fā)和安排最佳的解決方案進而降低開發(fā)網(wǎng)絡(luò)化利用的用度和復(fù)雜性這一宏大上風,很多廠家都表現(xiàn)將對J2EE給予支撐,并將J2EE技巧作為大型BtoB市場和海量交易處理的安全穩(wěn)固的端到端平臺。J2EE技巧的基礎(chǔ)就是J2SE標準版,它鞏固了標準版中的很多優(yōu)點。其終極目標就是成為一個能夠使企業(yè)開發(fā)者大幅縮短投放市場時間的系統(tǒng)結(jié)構(gòu)。它為機動配置各種多層企業(yè)利用軟件,特別是B2B、B2C等電子商務(wù)利用,供給了壯大的服務(wù)功效。最近又新加了Connector API服務(wù),使企業(yè)利用的開發(fā)和安排有了一系列成熟的技巧。
J2SE
J2SE是Java 2平臺的標準版, 它實用于桌面系統(tǒng),供給CORBA標準的ORB技巧,聯(lián)合Java的RMI支撐散布式互把持環(huán)境。它運行在Java虛擬機上。在引進了Java IDL后, J2SE支撐IIOP通信。它是高可移植性、異構(gòu)性的實現(xiàn)環(huán)境和硬朗平臺,也是實現(xiàn)可伸縮性、可移植性、散布式異構(gòu)互把持利用軟件開發(fā)的標準平臺。
J2ME J2ME供給了HTTP高級Internet協(xié)議,使移動電話能以Client/Server方法直接訪問Internet的全部信息,不同的Client訪問不同的文件,此外還能訪問本地存儲區(qū),供給最高效率的無線交換。J2ME是Java 2平臺的微型版,它分成CDC(connected device configuration)和CLDC(connected limited device configuration)兩部分。CDC運行在連接虛擬機上,為手提式盤算機一類較復(fù)雜的移動設(shè)備供給給用平臺;CLDC運行在核心虛擬機(KVM)上,它實現(xiàn)MIDP(Mobile Information Device Profile)移動信息設(shè)備利用平臺,即針對手機之類的設(shè)備建立移動盤算平臺。
在小型的J2ME(Java 2 Micro Edition)方面,重要是利用在內(nèi)存容量小、體積也較小的電子裝置上。小至智能卡、舉動電話,個人數(shù)字助理都是運用J2ME的最佳平臺。Java在Palm的利用上,PalmOS 4.0內(nèi)含KJava,Sun也推出針對PalmOS應(yīng)用的J2ME版本。所以,以既有的Java程序設(shè)計知識,就可以在Palm PDA上開發(fā)出Palm的各式各樣利用系統(tǒng)。Java和Palm這兩個標準平臺的聯(lián)合,將是下一波PDA利用的趨勢。Java在手機的利用上,Nokia、Motorola、Ericsson 都將推出利用J2ME技巧的新手機,所以Java程序設(shè)計師有更多的平臺可供施展。此種聯(lián)合J2ME及無線通信技巧的無線開放利用平臺,將供給舉動商務(wù)極佳的解決方案。
在中型的J2SE(Java 2 Standard Edition)方面,Sun推出一個新的解決方案,稱為Java Web Start。本來的Java Applet是在WebBrowser 中間開出一塊方形區(qū)域來履行Java程序,但是這樣在履行效能和兼容性上都受限于原有的 Web Browser?,F(xiàn)在新推出的Java Web Start則是在把持系統(tǒng)上直接履行的Java Application,但是可以在網(wǎng)頁上激活。如此一來既可和網(wǎng)頁聯(lián)合,在履行上也更快、更有效率。并且,Sun和IBM都將推出支撐64位運算的Java版本,這對一般盤算機上履行的客戶端Java利用系統(tǒng)的開發(fā)將會是一大利器。
另外在大型的J2EE(Java 2 Enterprise Edition)利用上,可以說"J2EE"已經(jīng)成為服務(wù)器運算環(huán)境的標準。Java Servlets、JSP(Java ServerPages)、EJB(Enterprise JavaBeans)、JavaMail、JDBC、JMS等,都是各家廠商產(chǎn)品開發(fā)的重點方向。J2EE兼容的是一般Intel個人盤算機(Linux、Windows.....)、麥金塔以及各家高效能高穩(wěn)固度的UNIX伺服主機,未來必定成為服務(wù)器運算市場上的重要選擇之一。
除了以上這三大Java組合之外,Java和XML的整合也是未來的重點。Sun公司已經(jīng)推出Java處理XML的標準延伸API - Java API for XML Parsing (JAXP),可以讓各家所制作的XML解析器有接口上的標準。所以在Java程序中,只要懂得一套API(JAXP)就可以完整處理XML文件,讓XML的利用更加方便。Java這個跨平臺的開發(fā)環(huán)境,加上XML這個跨平臺的材料格式,此種跨平臺上風組合勢將成為未來訊息傳遞及材料交換的重要利用技巧,如虎添翼地聯(lián)合成一個最佳的跨平臺解決方案。
藉由J2SE (Java 2 Standard Edition)可以開發(fā)在PC上的利用軟件,藉由J2ME (Java 2 Micro Edition) 可以跨足更寬大的家電、智能卡、電子裝置等市場,再藉由J2EE (Java 2 Enterprise Edition ) 可以整合伺服主機運算環(huán)境。Java技巧的利用領(lǐng)域幾乎已經(jīng)無所不在,Java技巧更可以在網(wǎng)際網(wǎng)絡(luò)及電子商務(wù)各領(lǐng)域中,供給全方位的解決方案。
隨著利用領(lǐng)域的不同,Java 有很多 API(Application Programming Interface),這些 API 分成三大類:
Java Core API:由 Sun 制定的基礎(chǔ) API,任何 Java 平臺都必須供給。
Java Standard Extension API (javax):由 Sun 制定的擴充 API,Java 平臺可以選擇性地供給或加裝。
廠商或組織所供給的 API:由各家公司或組織所供給。
其中 Core API 和 Standard Extension API 已經(jīng)逐漸涵蓋了大部份的信息利用領(lǐng)域,例如多媒體、數(shù)據(jù)庫、Web、企業(yè)運算、語音、實時系統(tǒng)、網(wǎng)絡(luò)、電話、影像處理、加解密、GUI、散布式運算 ......。假如你有某項需求尚未有標準的 Java API 可遵守,你可以向 Sun 提出制定新 API 的懇求。經(jīng)過審核之后,你的請求可能會通過、駁回 ...... 等。假如通過,就會開端進進制定 API 的程序。Java API 的制定過程由于公然,且經(jīng)過很多業(yè)界技巧領(lǐng)先公司的共同參與,所以相當完善而優(yōu)良。
EJB的生態(tài)環(huán)境 在sun公司供給的EJB規(guī)范中,我們一個完整的基于EJB的散布式盤算結(jié)構(gòu)由六個角色組成,這六個角色可以由不同的開發(fā)商供給,每個角色所作的工作必須遵守Sun公司供給的EJB規(guī)范,以保證彼此之間的兼容性。
EJB組件開發(fā)者: 開發(fā)并銷售 EJB。
利用組合者: 將不同的 EJB 搭建成利用。
安排者: 應(yīng)用相應(yīng)工具在運行環(huán)境下配置 EJB。
EJB 服務(wù)器供給者: 開發(fā)并銷售 EJB 服務(wù)器
EJB 容器供給商: 開發(fā)并銷售 EJB 容器
系統(tǒng)治理員: 監(jiān)督運行時情況
1、EJB組件開發(fā)者(Enterprise Bean Provider)
EJB組件開發(fā)者負責開發(fā)履行貿(mào)易邏輯規(guī)矩的EJB組件,開發(fā)出的EJB組件打包成ejb-jar文件。EJB組件開發(fā)者負責定義EJB的remote和home接口,編寫履行貿(mào)易邏輯的EJB class,供給安排EJB的安排文件(deployment descriptor)。安排文件包含EJB的名字,EJB用到的資源配置,如JDBC等。EJB組件開發(fā)者是范例的貿(mào)易利用開發(fā)領(lǐng)域?qū)<摇?
EJB組件開發(fā)者不需要精通系統(tǒng)級的編程,因此,不需要知道一些系統(tǒng)級的處理細節(jié),如事務(wù)、同步、安全、散布式盤算等。
2、利用組合者(Application Assembler)
利用組合者負責利用各種EJB組合一個完整的利用系統(tǒng)。利用組合者有時需要供給一些相干的程序,如在一個電子商務(wù)系統(tǒng)里,利用組合者需要供給JSP(Java Server Page)程序。
利用組合者必須把握所用的EJB的home和remote接口,但不需要知道這些接口的實現(xiàn)。
3、安排者(Deployer)
安排者負責將ejb-jar文件安排到用戶的系統(tǒng)環(huán)境中。系統(tǒng)環(huán)境包含某種EJB Server和EJB Container。安排者必須保證所有由EJB組件開發(fā)者在安排文件中聲明的資源可用,例如,安排者必須配置好EJB所需的數(shù)據(jù)庫資源。
安排過程分兩步:安排者首先利用EJB Container供給的工具天生一些類和接口,使EJB Container能夠利用這些類和接口在運行狀態(tài)治理EJB。 安排者安裝EJB組件和其他在上一步天生的類到EJB Container中。 安排者是某個EJB運行環(huán)境的專家。
某些情況下,安排者在安排時還需要懂得EJB包含的業(yè)務(wù)方法,以便在安排完成后,寫一些簡略的程序測試。
4、EJB 服務(wù)器供給者(EJB Server Provider)
EJB 服務(wù)器供給者是系統(tǒng)領(lǐng)域的專家,精通散布式交易治理,散布式對象治理及其它系統(tǒng)級的服務(wù)。EJB 服務(wù)器供給者一般由把持系統(tǒng)開發(fā)商、中間件開發(fā)商或數(shù)據(jù)庫開發(fā)商供給。
在目前的EJB規(guī)范中,假定EJB 服務(wù)器供給者和EJB 容器供給者來自同一個開發(fā)商,所以,沒有定義EJB 服務(wù)器供給者和EJB容器供給者之間的接口標準。
5、EJB 容器供給者(EJB Container Provider)
EJB 容器供給者供給以下功效:
供給EJB安排工具為安排好的EJB組件供給運行環(huán)境 。EJB容器負責為EJB供給交易治理,安全治理等服務(wù)。
EJB 容器供給者必須是系統(tǒng)級的編程專家,還要具備一些利用領(lǐng)域的經(jīng)驗。EJB 容器供給者的工作重要集中在開發(fā)一個可伸縮的,具有交易治理功效的集成在EJB 服務(wù)器中的容器。EJB 容器供給者為EJB組件開發(fā)者供給了一組標準的、易用的API訪問EJB 容器,使EJB組件開發(fā)者不需要懂得EJB服務(wù)器中的各種技巧細節(jié)。
EJB容器供給者負責供給系統(tǒng)監(jiān)測工具用來實時監(jiān)測EJB容器和運行在容器中的EJB組件狀態(tài)。
6、系統(tǒng)治理員(System Administrator)
系統(tǒng)治理員負責為EJB服務(wù)器和容器供給一個企業(yè)級的盤算和網(wǎng)絡(luò)環(huán)境。
系統(tǒng)治理員負責利用EJB 服務(wù)器和容器供給的監(jiān)測治理工具監(jiān)測EJB組件的運行情況。
將責任分別的另一個利益是在代碼級上,可以將基于EJBs的系統(tǒng)邏輯的分派給更合適的專家。SUN的EJB規(guī)范建議應(yīng)用幾個獨立的角色,對于斷定運作環(huán)境的責任鏈是非常重要的。舉例說,EJB供給者是由貿(mào)易專家和分析職員扮演的角色,他們斷定一個組織內(nèi)的最佳信息流程。但是仍然有Second Domain Expert,如利用程序匯編職員,他們集成不同的EJB組件并確保它可以確保滿足利用程序的需求。
還有兩種角色回進到系統(tǒng)級的部分,第一個是配置職員,他們負責實際的安裝和配置基于EJB的系統(tǒng)。這需要有設(shè)置目錄服務(wù)和集成現(xiàn)有利用程序的經(jīng)驗。第二個是系統(tǒng)治理員,他們要供給全天的監(jiān)督和支撐,確保利用程序正常運作。盡管系統(tǒng)治理員這個角色不需要是Java編程專家,但是他需要能夠搪塞以下標題:
設(shè)置Java Virtual Machine (JVM)并關(guān)接洽統(tǒng)環(huán)境參數(shù)(如:CLASSPATH)
應(yīng)用Java Archive (jar)命令保存類文件
懂得WEB服務(wù)器和Servlet的工作原理。
要能通過監(jiān)督運行中程序的狀態(tài)斷定優(yōu)化方法。
很明顯,有些角色是可以交叉的,比如系統(tǒng)治理員和配置職員。盡管配置職員可能是將類文件復(fù)制到服務(wù)器而系統(tǒng)治理員需要斷定配置職員是否復(fù)制到了正確的地位。
相關(guān)網(wǎng)址:
http://www.linuxaid.com.cn/support/showfom.jsp?i=2984 EJB技巧的基礎(chǔ)是另外兩種技巧:RMI-IIOP和JNDI。要想懂得EJB,必定要先懂得RMI-IIOP和JNDI。因此,我們在先容EJB細節(jié)之前,先懂得這兩項技巧。我們的先容比較基礎(chǔ),因此大多數(shù)組織只要懂得這些就已經(jīng)夠了。
Java RMI-IIOP Java RMI-IIOP(Java Remote Method Invocation over the Internet Inter-ORB Protocol)是J2EE的網(wǎng)絡(luò)機制。Java RMI-IIOP答應(yīng)你編寫散布式對象,使得對象的通信領(lǐng)域能夠在內(nèi)存中,跨Java虛擬機,跨物理設(shè)備。
Remote Method Invocation RPC(remote procedure call)是一臺機器的過程
調(diào)用另一臺機器的過程的過程。而remote method invocation則比RPC的概念更進一步,答應(yīng)散布式對象間的通信。RMI-IIOP答應(yīng)調(diào)用
遠程對象的方法,而不僅僅是過程。這有利于面向?qū)ο缶幊獭ava RMI (Remote Method Invocation 遠程方法調(diào)用)是用Java在JDK1.1中實現(xiàn)的,它大大加強了Java開發(fā)散布式利用的能力。Java作為一種風靡一時的網(wǎng)絡(luò)開發(fā)語言,其宏大的威力就體現(xiàn)在它壯大的開發(fā)散布式網(wǎng)絡(luò)利用的能力上,而RMI就是開發(fā)百分之百純Java的網(wǎng)絡(luò)散布式利用系統(tǒng)的核心解決方案之一。實在它可以被看作是RPC的Java版本。但是傳統(tǒng)RPC并不能很好地利用于散布式對象系統(tǒng)。而Java RMI 則支撐存儲于不同地址空間的程序級對象之間彼此進行通信,實現(xiàn)遠程對象之間的無縫遠程調(diào)用。
remote method invocation決不簡略,需要考慮幾個標題:
marshalling和unmarshalling.在不同機器間通過網(wǎng)絡(luò)傳遞變量(包含Java基礎(chǔ)類型和對象),假如目標機器表現(xiàn)數(shù)據(jù)的方法和原機器不同該怎么辦?例如二進制庫不同。因此marshalling和unmarshalling就是傳遞變量的過程。
變量傳遞方法.變量有兩種傳遞方法:pass-by-value和pass-by-reference。對于前者,你的目標方法只需應(yīng)用一份copy,但對于后者,遠程方法對變量的任何修正都會影響到源數(shù)據(jù)。
網(wǎng)絡(luò)和機器的不穩(wěn)固.需要有一種機制保證一個JVM崩潰之后,不會影響系統(tǒng)的正常運作。
在 Java 散布式對象模型中,remote object 是這樣一種對象:它的方法可以從其它 Java 虛擬機(可能在不同的主機上)中調(diào)用。該類型的對象由一種或多種 remote interfaces(它是聲明遠程對象方法的 Java 接口)描寫。遠程方法調(diào)用 (RMI) 就是調(diào)用遠程對象上遠程接口的方法的動作。更為重要的是,遠程對象的方法調(diào)用與本地對象的方法調(diào)用語法雷同。
Remote Interface RMI-IIOP遵守了接口和實現(xiàn)的原則。你寫的所有網(wǎng)絡(luò)代碼都是利用于接口,而不是實現(xiàn)。實際上,你必須應(yīng)用RMI-IIOP中的范例,沒有其它的選擇。直接在你的對象實現(xiàn)上履行遠程調(diào)用是不可能的,你只能在對象類的接口上單獨進行這一把持。
所以我們在應(yīng)用RMI-IIOP時,你必須建立一個客戶接口,叫做remote interface。這個遠程接口應(yīng)當擴大java.rmi.Remote接口。
Remote Object Implementation 遠程對象和客戶機的物理地位并不是很重要。可以運行在同一地址空間或是跨Internet運行。
為了使對象成為一個遠程對象,你需要履行一下步驟:
持續(xù)javax.rmi.PortableRemoteObject。PortableRemoteObject是進行遠程調(diào)用的基類,當你的遠程對象調(diào)用結(jié)構(gòu)器時,PortableRemoteObject對象的結(jié)構(gòu)器也會主動被調(diào)用。
不持續(xù)javax.rmi.PortableRemoteObject。假如你的遠程對象需要持續(xù)其它的類,而Java不答應(yīng)多重持續(xù),因此你不能持續(xù)PortableRemoteObject。這時,你需要手動調(diào)用javax.rmi.PortableRemoteObject.exportObject()。
Stub和Skeletons
我們來看看在RMI-IIOP背后隱躲的網(wǎng)絡(luò)架構(gòu)。RMI-IIOP的一個利益就是你可以不用管你要調(diào)用的對象是本地的還是遠程的。這就叫做local/remote transparency。
RMI利用程序通常包含兩個獨立的程序:服務(wù)器程序和客戶機程序。范例的服務(wù)器利用程序?qū)?chuàng)立多個遠程對象,使這些遠程對象能夠被引用,然后等候客戶機調(diào)用這些遠程對象的方法。而范例的客戶機程序則從服務(wù)器中得到一個或多個遠程對象的引用,然后調(diào)用遠程對象的方法。RMI為服務(wù)器和客戶機進行通信和信息傳遞供給了一種機制。
在與遠程對象的通信過程中,RMI應(yīng)用標準機制:stub和skeleton。遠程對象的stub擔負遠程對象的客戶本地代表或代理人角色。調(diào)用程序?qū)⒄{(diào)用本地stub的方法,而本地stub將負責履行對遠程對象的方法調(diào)用。在RMI中,遠程對象的stub與該遠程對象所實現(xiàn)的遠程接口集雷同。調(diào)用stub的方法時將履行下列把持:(1) 初始化與包含遠程對象的遠程虛擬機的連接;(2) 對遠程虛擬機的參數(shù)進行編組(寫進并傳輸);(3) 等候方法調(diào)用成果;(4) 解編(讀?。┓祷刂祷蚍祷氐漠惓#?5) 將值返回給調(diào)用程序。為了向調(diào)用程序展現(xiàn)比較簡略的調(diào)用機制,stub將參數(shù)的序列化和網(wǎng)絡(luò)級通信等細節(jié)隱躲了起來。在遠程虛擬機中,每個遠程對象都可以有相應(yīng)的skeleton(在JDK1.2環(huán)境中無需應(yīng)用skeleton)。Skeleton負責將調(diào)用分配給實際的遠程對象實現(xiàn)。它在吸收方法調(diào)用時履行下列把持:(1) 解編(讀取)遠程方法的參數(shù);(2) 調(diào)用實際遠程對象實現(xiàn)上的方法;(3) 將成果(返回值或異常)編組(寫進并傳輸)給調(diào)用程序。stub和skeleton由rmic編譯器天生。
要實現(xiàn)local/remote transparency可沒有那么簡略。為了屏蔽你調(diào)用的是遠端主機上的對象,RMI-IIOP需要模仿一個本地對象供你調(diào)用。這個本地對象叫做stub。它負責吸收本地的方法調(diào)用懇求,把這些懇求委托給真正實現(xiàn)它們的對象(可以通過網(wǎng)絡(luò)定位)。這樣就使得遠程調(diào)用看起來就和本地調(diào)用一樣。
利用RMI編寫散布式對象利用程序需要完成以下工作:(1) 定位遠程對象。利用程序可應(yīng)用兩種機制中的一種得到對遠程對象的引用。它既可用RMI的簡略命名工具rmiregistry來注冊它的遠程對象,也可以將遠程對象引用作為慣例把持的一部分來進行傳遞和返回。(2)與遠程對象通信。遠程對象間通信的細節(jié)由RMI處理,對于程序員來說,遠程通信看起來就像標準的Java方法調(diào)用。(3)給作為參數(shù)或返回值傳遞的對象加載類字節(jié)碼。由于RMI答應(yīng)調(diào)用程序?qū)⒓僇ava對象傳給遠程對象,所以,RMI將供給必要的機制,既可以加載對象的代碼又可以傳輸對象的數(shù)據(jù)。在RMI散布式利用程序運行時,服務(wù)器調(diào)用注冊服務(wù)程序以使名字與遠程對象相干聯(lián)??蛻魴C在服務(wù)器上的注冊服務(wù)程序中用遠程對象的名字查找該遠程對象,然后調(diào)用它的方法。
定位遠程對象。利用程序可應(yīng)用兩種機制中的一種得到對遠程對象的引用。它既可用 RMI 的簡略命名工具 rmiregistry 來注冊它的遠程對象;也可將遠程對象引用作為慣例把持的一部分來進行傳遞和返回。
與遠程對象通信。遠程對象間通信的細節(jié)由 RMI 處理;對于程序員來說,遠程通信看起來就象標準的 Java 方法調(diào)用。給作為參數(shù)或返回值傳遞的對象加載類字節(jié)碼由于 RMI答應(yīng)調(diào)用程序?qū)⒓?Java 對象傳給遠程對象,所以 RMI 將供給必要的機制,既可以加載對象的代碼又可以傳輸對象的數(shù)據(jù)。服務(wù)器調(diào)用注冊服務(wù)程序以使名字與遠程對象相干聯(lián)。客戶機在服務(wù)器注冊服務(wù)程序中用遠程對象的名字查找該遠程對象,然后調(diào)用它的方法。RMI 能用 Java系統(tǒng)支撐的任何 URL 協(xié)議(例如 HTTP、FTP、file 等)加載類字節(jié)碼。
stub只是解決了一半的標題。我們還希看遠程對象也不用考慮網(wǎng)絡(luò)標題。因此遠程對象也需要一個本地的skeleton來吸收調(diào)用。skeleton吸收網(wǎng)絡(luò)調(diào)用并把調(diào)用委托給遠程對象實現(xiàn)。
你的J2EE服務(wù)器應(yīng)當供給一種方法來產(chǎn)生必須的stub和skeleton,以減輕你的對網(wǎng)絡(luò)標題考慮的累贅。范例的是通過命令行工具來完成,例如sun的J2EE參考實現(xiàn)包就應(yīng)用了一個名為rmic(RMI compiler)的工具來產(chǎn)生stub和skeleton類。你應(yīng)當把stub安排在客戶機上,并把skeleton安排在服務(wù)器上。
對象序列化和變量傳遞
在RMI散布式利用系統(tǒng)中,服務(wù)器與客戶機之間傳遞的Java對象必須是可序列化的對象。不可序列化的對象不能在對象流中進行傳遞。對象序列化擴大了核心Java輸進/輸出類,同時也支撐對象。對象序列化支撐把對象編碼以及將通過它們可訪問到的對象編碼變成字節(jié)流;同時,它也支撐流中對象圖形的互補重結(jié)構(gòu)。序列化用于輕型持久性和借助于套接字或遠程方法調(diào)用(RMI)進行的通信。序列化中現(xiàn)在包含一個 API(Application Programming Interface,利用程序接口),答應(yīng)獨立于類的域指定對象的序列化數(shù)據(jù),并答應(yīng)應(yīng)用現(xiàn)有協(xié)議將序列化數(shù)據(jù)域?qū)戇M流中或從流中讀取,以確保與缺省讀寫機制的兼容性。
為編寫利用程序,除多數(shù)瞬態(tài)利用程序外,都必須具備存儲和檢索 Java對象的能力。以序列化方法存儲和檢索對象的要害在于供給重新結(jié)構(gòu)該對象所需的足夠?qū)ο鬆顟B(tài)。存儲到流的對象可能會支撐 Serializable(可序列化)或 Externalizable(可外部化)接口。對于Java對象,序列化情勢必須能標識和校驗存儲其內(nèi)容的對象所屬的 Java類,并且將該內(nèi)容還原為新的實例。對于可序列化對象,流將供給足夠的信息將流的域還原為類的兼容版本。對于可外部化對象,類將全權(quán)負責其內(nèi)容的外部格式。序列化 Java 對象的目標是:供給一種簡略但可擴充的機制,以序列化方法掩護 Java對象的類型及安全屬性;具有支撐編組和解編的擴大能力以滿足遠程對象的需要;具有可擴大性以支撐 Java 對象的簡略持久性;只有在自定義時,才需對每個類供給序列化自實現(xiàn);答應(yīng)對象定義其外部格式。
java.rmi.Remote 接口 在 RMI 中,遠程接口是聲明了可從遠程 Java 虛擬機中調(diào)用的方法集。遠程接
口必須滿足下列請求:
遠程接口至少必須直接或間接擴大 java.rmi.Remote 接口。
遠程接口中的方法聲明必須滿足下列遠程方法聲明的請求:
遠程方法聲明在其 throws 子句中除了要包含與利用程序有關(guān)的異常(留心與利用程序有關(guān)的異常無需擴大 java.rmi.RemoteException )之外,還必須包含 java.rmi.RemoteException 異常(或它的超類,例如java.io.IOException 或 java.lang.Exception )。
遠程方法聲明中,作為參數(shù)或返回值聲明的(在參數(shù)表中直接聲明或嵌進到參數(shù)的非遠程對象中)遠程對象必須聲明為遠程接口,而非該接口的實現(xiàn)類。
java.rmi.Remote 接口是一個不定義方法的標記接口:
public interface Remote
遠程接口必須至少擴大 java.rmi.Remote 接口(或其它擴大java.rmi.Remote 的遠程接口)。然而,遠程接口在下列情況中可以擴大非遠程接口:
遠程接口也可擴大其它非遠程接口,只要被擴大接口的所有方法(假如有)滿足遠程方法聲明的請求。
例如,下面的接口 BankAccount 即為訪問銀行帳戶定義了一個遠程接口。它包含往帳戶存款、使帳戶收支平衡和從帳戶取款的遠程方法:
public interface BankAccount extends java.rmi.Remote
{
public void deposit(float amount)
throws java.rmi.RemoteException;
public void withdraw(float amount)
throws OverdrawnException, java.rmi.RemoteException;
public float getBalance()
throws java.rmi.RemoteException;
}
下例闡明了有效的遠程接口 Beta。它擴大非遠程接口 Alpha(有遠程方法)和接口 java.rmi.Remote:
public interface Alpha
{
public final String okay = "constants are okay too";
public Object foo(Object obj)
throws java.rmi.RemoteException;
public void bar() throws java.io.IOException;
public int baz() throws java.lang.Exception;
}
public interface Beta extends Alpha, java.rmi.Remote {
public void ping() throws java.rmi.RemoteException;
}
RemoteException 類 java.rmi.RemoteException 類是在遠程方法調(diào)用期間由 RMI 運行時所拋出的異常的超類。為確保應(yīng)用 RMI 系統(tǒng)的利用程序的硬朗性,遠程接口中聲明的遠程方法在其 throws 子句中必須指定 java.rmi.RemoteException(或它的超類,例如 java.io.IOException 或 java.lang.Exception)。
當遠程方法調(diào)用由于某種原因失敗時,將拋出 java.rmi.RemoteException 異常。遠程方法調(diào)用失敗的原因包含:
通信失?。ㄟh程服務(wù)器不可達或拒盡連接;連接被服務(wù)器封閉等。)
參數(shù)或返回值傳輸或讀取時失敗
協(xié)議毛病
RemoteException 類是一個已檢驗的異常(必須由遠程方法的調(diào)用程序處理并經(jīng)編譯器檢驗的異常),而不是 RuntimeException。
RemoteObject 類及其子類 RMI 服務(wù)器函數(shù)由 java.rmi.server.RemoteObject 及其子類java.rmi.server.RemoteServer、java.rmi.server.UnicastRemoteObject和 java.rmi.activation.Activatable 供給。
java.rmi.server.RemoteObject 為對遠程對象敏感的 java.lang.Object方法、hashCode、 equals 和 toString 供給實現(xiàn)。
創(chuàng)立遠程對象并將其導(dǎo)出(使它們可為遠程客戶機利用)所需的方法由類UnicastRemoteObject 和 Activatable 供給。子類可以辨認遠程引用的語義,例如服務(wù)器是簡略的遠程對象還是可激活的遠程對象(調(diào)用時將履行的遠程對象)。java.rmi.server.UnicastRemoteObject 類定義了單體(單路傳送)遠程對象,其引用只有在服務(wù)器過程活著時才有效。類 java.rmi.activation.Activatable 是抽象類,它定義的 activatable遠程對象在其遠程方法被調(diào)用時開端履行并在必要時自己封閉。
實現(xiàn)遠程接口 實現(xiàn)遠程接口的類的一般規(guī)矩如下:
該類通常擴大 java.rmi.server.UnicastRemoteObject,因而將持續(xù)類java.rmi.server.RemoteObject 和java.rmi.server.RemoteServer 供給的遠程行動。
該類能實現(xiàn)任意多的遠程接口。
該類能擴大其它遠程實現(xiàn)類。
該類能定義遠程接口中不涌現(xiàn)的方法,但這些方法只能在本地應(yīng)用而不能在遠程應(yīng)用。
例如,下面的類 BankAcctImpl 實現(xiàn) BankAccount 遠程接口并擴大java.rmi.server.UnicastRemoteObject 類:
package mypackage;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class BankAccountImpl extends UnicastRemoteObject implements
BankAccount
{
private float balance = 0.0;
public BankAccountImpl(float initialBalance)
throws RemoteException
{
balance = initialBalance;
}
public void deposit(float amount) throws RemoteException
{
...
}
public void withdraw(float amount) throws OverdrawnException,
RemoteException
{
...
}
public float getBalance() throws RemoteException
{
...
}
}
留心:必要時,實現(xiàn)遠程接口的類能擴大除java.rmi.server.UnicastRemoteObject 類以外的其它一些類。但實現(xiàn)類此時必須承擔起必定的責任,即導(dǎo)出對象(由 UnicastRemoteObject 結(jié)構(gòu)函數(shù)負責)和實現(xiàn)從 java.lang.Object 類持續(xù)的 hashCode、 equals 和toString 方法的正確遠程語義(假如需要)。
遠程方法調(diào)用中的參數(shù)傳遞
傳給遠程對象的參數(shù)或源于它的返回值可以是任意可序列化的 Java 對象。這包含 Java 基礎(chǔ)類型, 遠程?Java 對象和實現(xiàn) java.io.Serializable 接口的非遠程 Java 對象。有關(guān)如何使類序列化的具體信息,參見 Java“對象序列化規(guī)范”。本地得不到的作為參數(shù)或返回值的類,可通過 RMI 系統(tǒng)進舉動態(tài)下載。
傳遞非遠程對象 非遠程對象將作為遠程方法調(diào)用的參數(shù)傳遞或作為遠程方法調(diào)用的成果返回時,是通過復(fù)制傳遞的;也就是應(yīng)用 Java 對象序列化機制將該對象序列化。因此,在遠程對象調(diào)用過程中,當非遠程對象作為參數(shù)或返回值傳遞時,非遠程對象的內(nèi)容在調(diào)用遠程對象之前將被復(fù)制。從遠程方法調(diào)用返回非遠程對象時,將在調(diào)用的虛擬機中創(chuàng)立新對象。
傳遞遠程對象 當將遠程對象作為遠程方法調(diào)用的參數(shù)或返回值傳遞時,遠程對象的 stub 程序即被傳遞出往。作為參數(shù)傳遞的遠程對象僅能實現(xiàn)遠程接口。
引用的完整性 假如一個對象的兩個引用在單個遠程方法調(diào)用中以參數(shù)情勢(或返回值情勢)從一個虛擬機傳到另一個虛擬機中,并且它們在發(fā)送虛擬機中指向同一對象,則兩個引用在吸收虛擬機中將指向該對象的同一副本。進一步說就是:在單個遠程方法調(diào)用中,RMI 系統(tǒng)將在作為調(diào)用參數(shù)或返回值傳遞的對象中保持引用的完整性。
類注解 當對象在遠程調(diào)用中被從一個虛擬機發(fā)送到另一個虛擬機中時,RMI 系統(tǒng)在調(diào)用流中用類的信息 (URL) 給類描寫符加注解,以便該類能在吸收器上加載。在遠程方法調(diào)用期間,調(diào)用可隨時下載類。
參數(shù)傳輸 為將 RMI 調(diào)用的參數(shù)序列化到遠程調(diào)用的目標文件里,需要將該參數(shù)寫進作為java.io.ObjectOutputStream 類的子類的流中。ObjectOutputStream 子類將籠罩 replaceObject 方法,目標是用其相應(yīng)的 stub 類代替每個遠程對象。對象參數(shù)將通過 ObjectOutputStream 的 writeObject 方法寫進流中。而ObjectOutputStream 則通過 writeObject 方法為每個寫進流中的對象(包含所寫對象所引用的對象)調(diào)用 replaceObject 方法。RMIObjectOutputStream子類的 replaceObject 方法返回下列值:
假如傳給 replaceObject 的對象是 java.rmi.Remote 的實例,則返回遠程對象的 stub 程序。遠程對象的 stub 程序通過對java.rmi.server.RemoteObject.toStub方法的調(diào)用而獲得。假如傳給 replaceObject 的對象不是 java.rmi.Remote 的實例,則只返回該對象。
RMI 的 ObjectOutputStream 子類也實現(xiàn) annotateClass 方法,該方法用類的地位注解調(diào)用流以便能在吸收器中下載該類。有關(guān)如何應(yīng)用 annotateClass的具體信息,參見“動態(tài)類加載”一節(jié)。由于參數(shù)只寫進一個 ObjectOutputStream,所以指向調(diào)用程序同一對象的引用將在吸收器那里指向該對象的同一副本。在吸收器上,參數(shù)將被單個ObjectInputStream 所讀取。
用于寫對象的 ObjectOutputStream(類似的還有用于讀對象的ObjectInputStream )的所有其它缺省行動將保存在參數(shù)傳遞中。例如,寫對象時對 writeReplace 的調(diào)用及讀對象時對 readResolve 的調(diào)用就是由 RMI的參數(shù)編組與解編流完成的。
與上述 RMI 參數(shù)傳遞方法類似,返回值(或異常)將被寫進ObjectOutputStream的子類并和參數(shù)傳輸?shù)恼{(diào)換行動雷同。
定位遠程對象 我們專門供給了一種簡略的領(lǐng)導(dǎo)名字服務(wù)器,用于存儲對遠程對象的已命名引用。應(yīng)用類 java.rmi.Naming 的基于 URL 的方法可以存儲遠程對象引用??蛻魴C要調(diào)用遠程對象的方法,則必須首先得到該對象的引用。對遠程對象的引用通常是在方法調(diào)用中以返回值的情勢取得。RMI 系統(tǒng)供給一種簡略的領(lǐng)導(dǎo)名字服務(wù)器,通過它得到給定主機上的遠程對象。java.rmi.Naming 類供給基于同一資源定位符 (URL) 的方法,用來綁定、再綁定、解開和列出位于某一主機及端口上的名字-對象對。
J2EE的十三種技巧
Java數(shù)據(jù)庫連接(JDBC) JDBC API以一個同一的方法訪問各種數(shù)據(jù)庫。與ODBC類似,JDBC將開發(fā)者和私有數(shù)據(jù)庫之間的標題隔離開來。由于它建立在Java上,因此JDBC可以供給平臺無關(guān)的數(shù)據(jù)庫訪問。
JDBC定義了4種不同的驅(qū)動,具體來說,包含有:
類型1:JDBC-ODBC橋
在JDBC剛產(chǎn)生時,JDBC-ODBC橋是非常有用的。通過它,開發(fā)者可以應(yīng)用JDBC來訪問一個ODBC數(shù)據(jù)源。毛病是,它需要在客戶機器上安裝有一個ODBC驅(qū)動,該機器通常是應(yīng)當運行微軟Windows系統(tǒng)的。應(yīng)用這一類的驅(qū)動器,你就會失往JDBC平臺無關(guān)的利益。此外,ODBV驅(qū)動器需要客戶真?zhèn)€治理。
類型2:JDBC-native驅(qū)動橋
JDBC-native驅(qū)動橋供給了一個建筑在本地數(shù)據(jù)庫驅(qū)動上的JDBC接口--沒有應(yīng)用ODBC。JDBC驅(qū)動將標準的JDBC調(diào)用轉(zhuǎn)變?yōu)閷?shù)據(jù)庫API的本地調(diào)用。應(yīng)用類型2的驅(qū)動也會失往JDBC平臺無關(guān)性的利益,并且需要安裝客戶真?zhèn)€本地代碼。
類型3:JDBC-network橋
JDBC-network橋不需要客戶真?zhèn)€數(shù)據(jù)庫驅(qū)動。它們應(yīng)用網(wǎng)絡(luò)-服務(wù)器中層來訪問一個數(shù)據(jù)庫。這會引出諸如負載均衡、連接池等技巧,數(shù)據(jù)緩沖也是可能的。由于類型3的驅(qū)動通??蓭硐鄬π〉南螺d時間,它是平臺無關(guān)的,并且不需要客戶真?zhèn)€安裝和治理,因此很適實用作Internet的利用。
類型4:純Java驅(qū)動
類型4應(yīng)用純Java數(shù)據(jù)庫驅(qū)動來供給直接的數(shù)據(jù)庫訪問。由于類型4驅(qū)動運行在客戶端,并且直接訪問數(shù)據(jù)庫,因此運行在這個模式暗示要應(yīng)用一個兩層的系統(tǒng)。要在一個n層的系統(tǒng)中應(yīng)用類型4的驅(qū)動,可以通過一個包含有數(shù)據(jù)訪問代碼的EJB,并且讓該EJB為它的客戶供給一個數(shù)據(jù)庫無關(guān)的服務(wù)。
Java命名和目錄接口(Java Naming and Directory Interface,JNDI) JNDI是Java Naming and Directory Interface 的簡寫,中意為:Java命名及目錄接口,它是為了對高級網(wǎng)絡(luò)利用開發(fā)中的應(yīng)用的目錄基礎(chǔ)結(jié)構(gòu)的訪問。實際上這個目錄是一個特別的數(shù)據(jù)庫,供給了對存儲數(shù)據(jù)的快速訪問,不象傳統(tǒng)的目錄服務(wù)訪問方法-你必須供給不同的API接口往訪問不同的目錄服務(wù)(如:LDAP,NIS,ADS等),而它供給了一種標準的API來訪問類型不同的目錄。據(jù)說,應(yīng)用完整的SDK可以開發(fā)那些JNDI還不支撐的目錄服務(wù)供給者。
JNDI是J2EE的一個API,供給了一套標準的接口,以定位用戶、機器、網(wǎng)絡(luò)、對象、以及服務(wù)。例如,你可以應(yīng)用JNDI來定位內(nèi)部網(wǎng)中的一臺打印機,你也可以應(yīng)用它來定位Java對象或連接到一個數(shù)據(jù)庫。JNDI可以用于EJB、RMI-IIOP、JDBC中。它是網(wǎng)絡(luò)查找定位的標準方法?! NDI API被用來訪問命名和目錄服務(wù)。它供給一個相容的模式來訪問和把持企業(yè)領(lǐng)域大的資源,例如一個利用服務(wù)器中的DNS、LDAP、本地文件系統(tǒng)或者對象。
在JNDI中,一個目錄結(jié)構(gòu)中的每一個節(jié)點被稱為context。每一個JNDI的名字都是與一個context相對的,沒有一個盡對名字的概念。一個利用可以應(yīng)用InitialContext類來得到它的第一個context:
Context ctx = new InitialContext();
通過這個初始的context,利用就可以經(jīng)過目錄樹定位到需要的資源或者對象。例如,假定你已經(jīng)在WebLogic Server中配置了一個EJB,并且在myApp.myEJB中綁定了home接口。EJB的客戶端,在得到這樣一個初始的context后,然后就可以應(yīng)用以下的代碼來定位到home接口:
MyEJBHome home = ctx.lookup( "myApp.myEJB" );
一旦你得到你所需對象的一個引用--在這個例子中,就是EJB的home接口--然后你可以調(diào)用它上面的方法。為了在一個context中查找到一個對象,JNDI還供給方法可以做到:
插進或者綁定一個對象到一個context中。在你配置一個EJB時,這是非常有效的方法;
從一個context中移往一個對象
列出一個context中的所有對象
創(chuàng)立和刪除subcontexts
企業(yè)Java Beans(Enterprise Java Beans,EJB) J2EE其中一個引人注視標技巧是EJB。它供給了一個架構(gòu)來開發(fā)和配置到客戶真?zhèn)€散布式貿(mào)易邏輯,因此可以明顯減少開發(fā)擴大性、高度復(fù)雜企業(yè)利用的難度。EJB規(guī)范定義了EJB組件應(yīng)當如何及何時與它們的容器交互。由容器來負責供給普通的服務(wù),例如目錄服務(wù)、事務(wù)治理、安全、資源池和容錯。
EJB規(guī)范定義了三類基礎(chǔ)的bean:
會話beans(session beans):會話beans為業(yè)務(wù)流程建模,由于他們通常表現(xiàn)履行某個動作,因此可以把它們當作是動詞。這個履行的動作可以是任何事情,例如增長數(shù)目,訪問數(shù)據(jù)庫,調(diào)用其它系統(tǒng),調(diào)用其它企業(yè)Bean。我們可以舉出很多的例子,包含一個計價引擎,一個工作流引擎,一個目錄引擎,一個信用卡認證中心,或一個網(wǎng)上證券交易引擎。
實體beans(Entity beans):這是持久保存數(shù)據(jù)的代表--范例的是存儲在數(shù)據(jù)庫中--因此在服務(wù)器崩潰后數(shù)據(jù)仍然存在。多個客戶端可以應(yīng)用EJB來表現(xiàn)同樣的數(shù)據(jù)。實體beans為企業(yè)數(shù)據(jù)建模,由于它們表現(xiàn)數(shù)據(jù)對象(就是緩存數(shù)據(jù)庫信息的Java對象),因此可以把它們當作名詞。實體beans的例子包含一種產(chǎn)品,一項訂單,一個雇員,一張信用卡,或一支股票。會話beans范例的方法是通過實體beans來實現(xiàn)業(yè)務(wù)目標的,例如一個證券交易引擎(會話beans)處理股票(實體beans)。
Message-Driven beans:Message-Driven beans也表現(xiàn)動作,這一點上它類似于會話beans。它們之間的不同點在于你只能夠通過發(fā)送消息給Message-Driven beans的方法來調(diào)用它們。Message-Driven beans的例子包含了吸收股票交易消息的beans,信用認證消息,或工作流消息。這些Message-Driven beans也可以調(diào)用其它的企業(yè)beans。
接著,我們討論無狀態(tài)和有狀態(tài)
無狀態(tài)的beans(Stateless beans):這是一個單一應(yīng)用的服務(wù),不掩護任何的狀態(tài),在服務(wù)器崩潰時也不再存在,而且生存期也相對地短。例如,一個無狀態(tài)的session bean可能用作履行溫度轉(zhuǎn)換。
有狀態(tài)的bean:它供給了一個傳統(tǒng)的與客戶端交互的方法,存儲客戶真?zhèn)€狀態(tài)。在線購物車就是這樣一個有狀態(tài)session ean的典范例子。有狀態(tài)session beans在服務(wù)器崩潰時也不再存在,而且生存期也相對地短,并且每個實例只可以用在一個單一的線程中。
JavaServer Pages (JSPs)
或許你已經(jīng)對微軟的Active Server Pages (ASPs)非常熟悉;JSP也是類似的技巧,不過它是平臺無關(guān)的。它們都是設(shè)計來贊助web內(nèi)容開發(fā)者應(yīng)用相對較少的代碼就可以創(chuàng)立動態(tài)的網(wǎng)頁。web設(shè)計者即使不懂得編程,也可以應(yīng)用JSP來創(chuàng)立動態(tài)的網(wǎng)頁。JavaServer Page是HTML代碼和Java代碼的混雜。在客戶懇求頁面的時候,服務(wù)器就會處理Java代碼,然后返回HTML頁面給瀏覽器。
你可以也聽過JHTML,它是一個舊的標準,現(xiàn)在已經(jīng)被JSP代替了。WebLogic Server不但支撐JSP,還支撐JHTML。不過,在默認設(shè)置下,WebLogic Server是不支撐JSP的(對于5.1版本)。你必須編輯weblogic.properties來激活web服務(wù)器,對于JSPServlet來說,也是這樣。
Java servlets
servlets供給的功效大部分JSP雷同,它采用的是一個有點不同的方法。JSP中大部分是HTML代碼,其中只有少量的Java代碼,而servlets則相反,它完整應(yīng)用Java編寫,并且產(chǎn)生HTML代碼。
servlet是一個在服務(wù)器上運行的Java小程序,它可以擴大Web服務(wù)器的功效。這些服務(wù)器真?zhèn)€利用可以在被懇求時動態(tài)履行,與傳統(tǒng)Web服務(wù)器上的CGI Perl腳本差未幾。CGI腳本和servlet的一個重要不同是:CGI腳本對于每次懇求都啟動一個全新的過程--需要額外的系統(tǒng)開銷--而servlet的履行只要在servlet引擎內(nèi)啟動一個獨立的線程就性了。因此Servlet的擴大性也更好。
在開發(fā)servlet時,你通常都要擴大javax.servlet.http.HttpServlet類,并且籠罩它的一些方法。感愛好的方法包含有:
service(): 作為command-specific方法的一個調(diào)度程序
doGet(): 處理來自一個客戶的HTTP GET懇求
doPost(): 處理來自一個客戶的HTTP POST懇求
還有一些其它的方法來處理不同類型的HTTP懇求--可參考HttpServlet API的文本來得到更多相干的信息。
Java IDL/CORBA 通過Java的IDL支撐,開發(fā)者可以將Java與CORBA集成。他們可以創(chuàng)立能配置在一個CORBA ORB中的Java對象,也可以創(chuàng)立作為配置在其它ORB內(nèi)的CORBA對象客戶真?zhèn)€Java類。對于通過Java將你的新利用和以前的系統(tǒng)集成,后者供給了一個另外的方法。
Java事務(wù)系統(tǒng)(JTA)/Java事務(wù)服務(wù)(JTS) JTA定義了一個標準的API,利用可以通過它來訪問事務(wù)監(jiān)控器。
JTS是CORBA OTS事務(wù)監(jiān)控器的一個基礎(chǔ)實現(xiàn)。JTS指定了一個事務(wù)治理器的實現(xiàn)(Transaction Manager),這個治理器在一個高級別上支撐Java事務(wù)API(JTA)規(guī)范,并且在一個低級別上實現(xiàn)了OMG OTS規(guī)范的Java映射。一個JTS事務(wù)治理器為利用服務(wù)器、資源治理器、standalone利用和通信資源治理器供給事務(wù)服務(wù)。
JavaMail和JavaBeans激活架構(gòu)(JavaBeans Activation Framework,JAF) JavaMail是一個用來訪問郵件服務(wù)器的API。JavaMail API供給了一套抽象類來模型化一個郵件系統(tǒng)。支撐SMTP和IMAP服務(wù)器。
JavaMail通過應(yīng)用JavaBeans Activation Framework (JAF) 來處理MIME加密的郵件附件。MIME字節(jié)流和Java對象間可以互相轉(zhuǎn)化。大多數(shù)的利用無需要直接應(yīng)用JAF。
Java信使服務(wù)(Java Messaging Service,JMS) JMS是一個用來和面向信息的中層通信的API。它不但支撐點對點的域,也支撐發(fā)布/訂閱域,并且供給對擔保信息傳送、事務(wù)信息傳送、持久信息和durable subscribers的支撐。對于將你的利用和以前的backend系統(tǒng)集成,JMS供給了另外一個方法。
擴大標記語言(Extensible Markup Language,XML) XML是一個用來定義其它標記語言的的語言。它可被用作貿(mào)易之間的數(shù)據(jù)共享。XML的發(fā)展是與Java離開的;不過,它的目標和Java類似,都是為了與平臺無關(guān)。通過將Java與XML聯(lián)合,你可以得到一個完整平臺無關(guān)的解決方案。多個公司都為在Java和XML間開發(fā)一個緊密的集成而工作。具體的信息,可瀏覽Sun站點的Java-XML部分(http://java.sun.com/xml),以及IBM的developerWorks的XML Zone部分(
http://www.ibm.com/developer/xml/)。