【寫在前面的一點廢話】 企業(yè)如今生活在一個全球化競爭的世界,他們需要應(yīng)用系統(tǒng)來滿足他們的業(yè)務(wù)需求,這些需求越來越復(fù)雜。 在這個全球化時代,公司分布不同區(qū)域,他們通過互聯(lián)網(wǎng)實現(xiàn)24*7的全天侯模式下跟不同國家進行業(yè)務(wù)往來?;诙鄠€數(shù)據(jù)中心以及必須處理不同貨幣和時區(qū)的國際化系統(tǒng),這樣以便降低成本和降低服務(wù)的響應(yīng)時間,并將業(yè)務(wù)數(shù)據(jù)存儲在可靠和安全的存儲上,同時為其客戶、員工和供應(yīng)商提供移動和Web方式的多種交互形式。 大多數(shù)公司必須將這些復(fù)雜的挑戰(zhàn)與其現(xiàn)有的企業(yè)信息系統(tǒng)(EIS)相結(jié)合,同時開發(fā)企業(yè)對企業(yè)(Business to Business)應(yīng)用程序,以便基于移動和地理定位模式的應(yīng)用程序與合作伙伴或企業(yè)對客戶系統(tǒng)進行通信溝通。 這樣,公司不得不協(xié)調(diào)存儲在不同位置的內(nèi)部數(shù)據(jù),由多種編程語言處理,并通過不同的協(xié)議進行路由。 當然,在無損失的情況下,企業(yè)必須這樣做,這意味著分布系統(tǒng)具有防止系統(tǒng)崩潰、高可用性、可擴展性和安全性等特性,同時,企業(yè)應(yīng)用必須面對變化和復(fù)雜性,并且應(yīng)該系統(tǒng)必須是健壯的。 這正是Java企業(yè)版(Java EE)創(chuàng)建的原因所在。 于1999年發(fā)布的Java EE的第一個版本(最初稱為J2EE)側(cè)重于企業(yè)面臨的問題:分布式組件。 從那時起,軟件應(yīng)用程序不得不適應(yīng)新的技術(shù)解決方案,如SOAP或RESTful Web服務(wù)。Java EE平臺已經(jīng)發(fā)展到通過提供各種標準規(guī)范的方法來滿足這些技術(shù)需求。 多年來,Java EE已經(jīng)發(fā)生變化,變得更加豐富、更簡單、更易于使用、更便攜和更加集成化。 那么,在本學(xué)習(xí)教程中,我將給出一個Java EE的總體概述,介紹其內(nèi)部架構(gòu),組件和服務(wù)后等,并介紹Java EE 7中的新功能特性。 1Java EE 簡史圖1-0總結(jié)了14年的Java EE演進。 Java EE以前稱為J2EE。 J2EE 1.2是由Sun開發(fā)的,并于1999年發(fā)布,包含10個JSR的總括規(guī)范。 當時人們總在在談?wù)揅ORBA,所以J2EE 1.2是在分布式系統(tǒng)的基礎(chǔ)上創(chuàng)建的。引入了企業(yè)Java Bean(EJB),支持遠程狀態(tài)和無狀態(tài)服務(wù)對象,并支持持久對象(實體bean)。 它們基于使用RMI-IIOP(遠程方法調(diào)用 - Internet Inter-ORB協(xié)議)作為底層協(xié)議的事務(wù)和分布式組件模型構(gòu)建。Web層有servlet和JavaServer Pages(JSP)技術(shù),JMS用于發(fā)送消息之用。 圖1-0 Java EE簡史 由J2EE 1.3開始,該規(guī)范是由Java社區(qū)進程(JCP)根據(jù)JSR 58開發(fā)的。實體bean的支持是強制性的,EJB引入了XML部署描述符來存儲元數(shù)據(jù)(在EJB 1.0中的一個文件中被序列化)。 該版本解決了使用遠程接口通過值傳遞參數(shù)的開銷,即通過引用本地接口并通過引用傳遞參數(shù)。 引入了J2EE連接器架構(gòu)(JCA)來實現(xiàn)Java EE連接到EIS(企業(yè)信息系統(tǒng))。 2003年發(fā)布的J2EE 1.4(JSR 151)在包含20個規(guī)范,并增加了對Web服務(wù)的支持。 EJB 2.1允許通過SOAP / HTTP調(diào)用會話bean。 創(chuàng)建定時服務(wù)以允許在指定的時間或間隔調(diào)用EJB。該版本為應(yīng)用程序的裝配和部署提供了更好的支持。 雖然它的支持者預(yù)測了它的偉大未來,但并不是所有的J2EE的承諾都實現(xiàn)了。使用它創(chuàng)建的系統(tǒng)太復(fù)雜,開發(fā)時間常常與用戶需求的復(fù)雜性成正比。 J2EE被視為重量級組件模型:難以測試,難以部署,難以運行。 就在那時, Struts,Spring或Hibernate等框架出現(xiàn)并導(dǎo)引出開發(fā)企業(yè)應(yīng)用程序的新方法。 幸運的是,2006年第二季度發(fā)布了Java EE 5(JSR 244),帶來了顯著的進步。 通過從開源框架中獲得了一些靈感,引入POJO編程模型??梢允褂米⑨尪x元數(shù)據(jù),并且XML描述符成為可選的。 從開發(fā)人員的角度來看,EJB 3和新的JPA比平臺的演變更具有飛躍性。JavaServer Faces(JSF)作為標準的表示層框架被引入,JAX-WS 2.0將JAX-RPC替換為 SOAP Web服務(wù)API。 在2009年,Java EE 6(JSR 316)遵循開發(fā)的方便之路,在整個平臺(包括Web層)中擁抱含注解、POJO編程和例外配置機制的概念。 它擁有豐富的創(chuàng)新,如全新的JAX-RS 1.1,Bean Validation 1.0和CDI 1.0; 它簡化了成熟的API,如EJB 3.1,并豐富了其他的,如JPA 2.0或EJB定時器服務(wù)。 但是Java EE 6的主要主題是可移植性(例如通過標準化全局JNDI命名),某些規(guī)范(通過修剪)的棄用,以及通過配置文件創(chuàng)建平臺的子集。 今天,Java EE 7帶來了許多新的規(guī)范(批量處理,websockets,JSON處理)以及改進其他規(guī)范。 Java EE 7還通過在大多數(shù)規(guī)范中采用CDI來提高技術(shù)之間的集成。 有機會,將在教程中,我想向您展示這些改進,以及Java Enterprise Edition已經(jīng)變得更加容易和豐富開發(fā)模式。 2 全局理解Java EE 7當想處理對的集合時,無需從開發(fā)自己的哈希表開始——集合API(應(yīng)用程序編程接口)就完全滿足需要了。 同樣,如果您需要一個簡單的Web應(yīng)用程序或支持事務(wù)、安全、可互操作和分布式的應(yīng)用程序,則不需要開發(fā)所有低級API:企業(yè)版Java就滿足需要。 正如Java標準版(Java SE)提供的處理集合的API一樣,Java EE提供了一種標準的事務(wù)API方法來處理Java 事務(wù),使用Java消息服務(wù)(JMS)進行消息傳遞,或者使用持久化 API(JPA)進行數(shù)據(jù)持久化。Java EE是針對企業(yè)應(yīng)用程序的一組規(guī)范,它可以被看作是Java SE的擴展,以便于開發(fā)分布式、健壯的、強大的和高可用性的應(yīng)用程序。 Java EE 7是一個重要的里程碑。不僅僅是遵循Java EE 6關(guān)注一個更簡單的開發(fā)模式,而且還增加了新的規(guī)范,并為現(xiàn)有特性增加了新的功能。另外,上下文依賴注入(CDI)正在成為所有這些新規(guī)范之間的集成點。 Java EE 7的發(fā)布與企業(yè)平臺發(fā)布十三周年緊密相連,將Java語言的優(yōu)勢與過去13年所獲得的經(jīng)驗結(jié)合起來.Java EE從開源社區(qū)的活力中獲益,同時也得益于嚴格的 JCP(Java Community Process)標準化進程。 今天,Java EE早已成為經(jīng)過驗證的優(yōu)秀平臺,其擁有經(jīng)驗豐富的開發(fā)人員、大型社區(qū)以及部署在公司服務(wù)器上運行著的諸多應(yīng)用系統(tǒng)。Java EE是一套規(guī)范的APIs,可用于構(gòu)建基于標準組件的多層應(yīng)用程序,這些組件部署在提供一系列服務(wù)的不同容器中。 接下來,我們從不同層面理解掌握Java EE 7的不同總體構(gòu)成。 2.1Java EE總體架構(gòu) Java EE是由不同容器實現(xiàn)的一組規(guī)范。容器是為其所托管的組件提供某些服務(wù)的Java EE運行時環(huán)境,例如生命周期管理,依賴注入,并發(fā)等。這些組件使用定義良好的規(guī)約與Java EE基礎(chǔ)架構(gòu)以及其他組件進行通信。在部署之前,需要以標準方式打包(按照定義的目錄結(jié)構(gòu),可壓縮到歸檔文件中)。注意,Java EE是Java SE平臺的超集,這意味著Java SE API可以由任何Java EE組件使用。 圖1-1顯示了容器之間的邏輯關(guān)系。箭頭表示一個容器訪問另一個容器所使用的協(xié)議。 例如,Web容器托管可以通過RMI-IIOP訪問EJB的servlet。 圖1-1 標準Java EE容器架構(gòu)關(guān)系 2.2Java EE構(gòu)件組成 Java EE運行時環(huán)境規(guī)范定義了Java EE“實現(xiàn)”(可以看作為中間件)必須支持的四種類型的構(gòu)件:
2.3Java EE容器 Java EE基礎(chǔ)架構(gòu)被劃分為稱為容器的邏輯域(見圖1-1)。每個容器都有一個特定的角色,支持一組API,并為組件提供服務(wù)(如安全性,數(shù)據(jù)庫訪問,事務(wù)處理,命名目錄,資源注入等)。容器隱藏技術(shù)復(fù)雜性并增強可移植性。根據(jù)要構(gòu)建的應(yīng)用程序的類型,將須了解每個容器的功能和約束,以便使用一個或多個。例如,如果您需要開發(fā)一個Web應(yīng)用,將開發(fā)具有EJB Lite層的JSF層,并將其部署到Web容器中。但是,如果您希望Web應(yīng)用程序能遠程調(diào)用業(yè)務(wù)層并使用消息傳遞和異步調(diào)用,那么您將需要Web和EJB容器。 Java EE標準定義了四種不同的容器:
2.4Java EE服務(wù) 容器為其部署的組件提供基礎(chǔ)服務(wù)。 作為開發(fā)人員,容器允許您集中精力實施業(yè)務(wù)邏輯,而不是解決企業(yè)應(yīng)用程序中面臨的技術(shù)問題。圖1-2顯示了每個容器提供的服務(wù)。 例如,Web和EJB容器提供連接器來訪問EIS,但不提供applet容器或ACC。Java EE提供以下服務(wù):
圖1-2 容器提供服務(wù)支持及關(guān)系圖 2.5Java EE網(wǎng)絡(luò)協(xié)議 如圖1-2所示,部署在容器中的組件可以通過不同的協(xié)議進行調(diào)用。 例如,部署在Web容器中的servlet可以使用HTTP以及在EJB容器中部署EJB端點的Web服務(wù)來調(diào)用。 以下是Java EE支持的協(xié)議列表:
2.6Java EE 打包 要部署在容器中,組件首先要封裝在標準的格式化存檔中。 Java SE定義了Java Archive(jar)文件,用于將多個文件(Java類,部署描述符,資源或外部庫)聚合到一個壓縮文件(基于ZIP格式)中。 如圖1-3所示,Java EE定義了基于通用jar格式的具有自己的打包格式的不同類型的模塊。 圖1-3 容器中打包歸檔格式 針對上述歸檔模式,說明如下: 其一,應(yīng)用程序客戶端模塊包含打包在jar文件中的Java類和其他資源文件。 該jar文件可以在Java SE環(huán)境或應(yīng)用程序客戶端容器中執(zhí)行。 像任何其他存檔格式一樣,jar文件包含一個可選的META-INF目錄,用于描述歸檔的元信息。 META-INF / MANIFEST.MF文件用于定義擴展和包相關(guān)數(shù)據(jù)。 如果部署在ACC中,則部署描述符可以可選地位于META-INF / application-client.xml。 其二,EJB模塊包含打包在jar文件(通常稱為EJB jar文件)中的一個或多個會話和/或消息驅(qū)動的bean(MDB)。 它包含一個可選的META-INF / ejb-jar.xml部署描述符,并且只能部署在EJB容器中。 其三,Web應(yīng)用程序模塊包含servlet,JSP,JSF頁面和Web服務(wù),以及任何其他Web相關(guān)文件(HTML和XHTML頁面,級聯(lián)樣式表(CSS),Java腳本,圖像,視頻等)。 從Java EE 6以來,Web應(yīng)用程序模塊還可以包含EJB Lite bean(EJB API的一個子集)。所有這些工件都封裝在帶有.war擴展名(通常稱為war文件或Web Archive)的jar文件中??蛇xWeb部署描述符在WEB-INF / web.xml文件中定義。 如果war包含EJB Lite bean,則可以在WEB-INF / ejb-jar.xml中設(shè)置可選的部署描述符。 Java.class文件放置在WEB-INF / classes目錄和依賴的jar文件的WEB-INF / lib目錄下。 其四,企業(yè)模塊可以包含零個或多個Web應(yīng)用程序模塊,零個或多個EJB模塊以及其他常用或外部庫。所有這些都被打包成企業(yè)歸檔(具有.ear擴展名的jar文件),以便各種部署模塊協(xié)同進行并發(fā)。 可選的企業(yè)模塊部署描述符在META-INF / application.xml文件中定義。特殊的lib目錄用于在模塊之間共享公共庫。 2.7注解和部署描述符 在編程范例中,有兩種方法:命令式編程和聲明式編程。語法編程規(guī)定了實現(xiàn)目標的算法(必須做的事情),而聲明式編程規(guī)定了如何實現(xiàn)這一目標(如何完成)。 在Java EE中,通過使用元數(shù)據(jù)(即注釋或/和部署描述符)完成聲明式編程。 如圖1-2所示,組件在容器中運行,此容器為組件提供了一組服務(wù).Metadata用于聲明和自定義這些服務(wù),并將附加信息與Java類、接口、構(gòu)造函數(shù)、方法、字段或參數(shù)相關(guān)聯(lián) 。 自從Java EE 5以來,注釋在企業(yè)平臺上一直在增長。它們使用元數(shù)據(jù)信息來修飾代碼(Java類,接口,字段,方法...)。 清單1-1顯示了一個POJO(普通Java對象),它使用類和屬性上的注釋來聲明某些行為。 @Stateless @Remote(ItemRemote.class) @Local(ItemLocal.class) @LocalBean public class ItemEJB implements ItemLocal, ItemRemote { @PersistenceContext(unitName = 'chapter01PU') private EntityManager em; public Book findBookById(Long id) { return em.find(Book.class, id); } } 代碼清單1-1:注解式EJB 聲明元數(shù)據(jù)的另一種方式是使用部署描述符。部署描述符(DD)是指與容器中組件一起部署的XML配置文件.Listing 1-2顯示了一個EJB部署描述符。 像大多數(shù)Java EE 7部署描述符一樣,它定義了http://xmlns./xml/ns/javaee命名空間,并包含版本屬性 規(guī)范。 xmlns:xsi='http://www./2001/XMLSchema-instance' ? xsi:schemaLocation='http://xmlns./xml/ns/javaee ? http://xmlns./xml/ns/javaee/ejb-jar_3_2.xsd' ? version='3.2'> 代碼清單1-2:EJB部署描述符 部署描述符需要與特殊的META-INF或WEB-INF目錄中的組件打包在一起,以備參考。 表1-1顯示了Java EE部署描述符和相關(guān)規(guī)范的列表 表1-1:JavaEE部署描述列表
由于Java EE 5大多數(shù)部署描述符是可選的,應(yīng)用可以使用注釋。或使用兩者中對應(yīng)用程序最好的方式即可。 注釋的最大優(yōu)點是它們顯著減少了開發(fā)人員編寫的代碼量,并且通過使用注釋可以避免編寫部署描述符的需要。 另一方面,部署描述符是可以更改的外部XML文件,而不需要修改源代碼和重新編譯。 如果您同時使用這兩者,當部署應(yīng)用程序或組件時則元數(shù)據(jù)將被部署描述符覆蓋(即XML優(yōu)先于注釋)。 2.8編程模型 大多數(shù)Java EE 7規(guī)范使用相同的編程模型。 它通常是一個POJO,它將一些元數(shù)據(jù)(注釋或XML)部署到容器中。 大多數(shù)時候,POJO甚至沒有實現(xiàn)一個接口或者擴展一個超類。 由于元數(shù)據(jù),容器知道應(yīng)用于此已部署組件的每一個服務(wù)。 在Java EE 7中,servlet,JSF支持bean,EJB,實體,SOAP和REST Web服務(wù)是帶可選XML部署描述符的注釋類。 清單1-3顯示了一個JSF支持bean,證明是具有單個CDI注釋的Java類。 清單1-3:JSF后端Bean @Named public class BookController { @Inject private BookEJB bookEJB; private Book book = new Book(); private List public String doCreateBook() { book = bookEJB.createBook(book); bookList = bookEJB.findBooks(); return 'listBooks.xhtml'; } // Getters, setters } EJB也遵循相同的模式。 如清單1-4所示,如果您需要在本地訪問EJB,則沒有接口的簡單注釋類就足夠了。 EJB也可以直接部署在war文件中,而不會先前封裝在jar文件中。 這使EJB成為可以從簡單的Web應(yīng)用程序到復(fù)雜的企業(yè)應(yīng)用程序使用的最簡單的事務(wù)組件。 代碼清單1-4:無狀態(tài)EJB @Stateless public class BookEJB { @Inject private EntityManager em; public Book findBookById(Long id) { return em.find(Book.class, id); } public Book createBook(Book book) { em.persist(book); return book; } } RESTful Web服務(wù)已經(jīng)進入現(xiàn)代應(yīng)用程序。 Java EE 7通過改進JAX-RS規(guī)范來滿足企業(yè)的需求。 如清單1-5所示,一個RESTful Web服務(wù)是一個響應(yīng)HTTP操作的帶有注釋的Java類。 代碼清單1-5:RESTFUL web服務(wù) @Path('books') public class BookResource { @Inject private EntityManager em; @GET @Produces({'application/xml', 'application/json'}) public List Query query = em.createNamedQuery('findAllBooks'); List return books; } |
|