???????????????????????????????? 作者 :?Allen | 文章來源 :?ccidnet |
我們?yōu)槭裁葱枰狫ava EE 5.0?
作為主流中間件技術(shù)標(biāo)準(zhǔn)J2EE誕生6年后的下一代企業(yè)級開發(fā)規(guī)范,Java EE 5.0從一開始就倍受關(guān)注,引發(fā)了無數(shù)辯論和眾多期盼。它重點關(guān)注目前Java應(yīng)用開發(fā)的熱點:運行可靠性、開發(fā)效率、擴展靈活性及企業(yè)應(yīng)用整合,順應(yīng)輕量級、簡單化趨勢,給開發(fā)者和企業(yè)帶來真正的實惠。
什么是Java EE 5.0?
“Do more with less work”,這是Java EE 5.0的正式宣言,也是其與J2EE 1.4最顯著的區(qū)別。Java EE 5.0提供了諸多新特性以簡化應(yīng)用的開發(fā),譬如:
? ? ?通過Annotation代替舊有的xml配置文件;
? ? ?重新設(shè)計的EJB 3.0變得輕量與簡單;
? ? ?基于組件化的JSF Web編程模型;
? ? ?與JAX-RPC相比更易使用的JAX-WS等Web Services相關(guān)規(guī)范;
? ? ?擁有了諸如依賴注入、AOP編程等以往開源框架才擁有的功能等等。
圖中藍(lán)底白字部分是Java EE 5新的功能,從下圖可以看到,在WEB層加入了JSF這個新的表現(xiàn)層框架。EJB從EJB2.0升級到EJB3.0。Java 5.0還加入了Annotations,通過Annotations引入,降低Java EE開發(fā)成本。
Java EE 5.0架構(gòu)圖
為什么我們還需要Java EE 5.0?
在談?wù)揓ava EE 5.0眾多新特性的時候,我們面對這樣一個問題:在J2EE 1.4依然占據(jù)主流開發(fā)地位,并且除官方標(biāo)準(zhǔn)以外,還擁有很多豐富的開源框架可供選擇的今天,為什么我們還需要Java EE 5.0?
首先,作為官方標(biāo)準(zhǔn)的J2EE 1.4,是一種過度理論化的計算模型,無論是開發(fā)效率還是運行期性能,都已經(jīng)日顯老態(tài);其次,在諸多開源框架的沖擊下,J2EE 1.4的功能局限性也日益暴露出來,譬如:與Entity Bean相比,Hibernate提供了更好的OR Mapping解決方案;與Session Bean相比,Spring Framework對Bean的管理更簡單,更高效,功能也更豐富;與單純的JSP/Servlet相比,Struts、WebWork能夠在更高層次上解決Web開發(fā)的復(fù)雜度問題。
人們是智慧的,業(yè)界既需要代表現(xiàn)實主義的官方標(biāo)準(zhǔn)和商業(yè)軟件的存在,也同時需要代表理想主義的開源組織和開源軟件的存在。尤其是在Java EE 越來越 Open的今天,我們甚至已經(jīng)忽略了哪些特性是官方標(biāo)準(zhǔn)應(yīng)該具備的、哪些特性是開源軟件應(yīng)該具有的。事實上,整個業(yè)界都在迫切等待下一代J2EE規(guī)范的誕生,而一旦該規(guī)范誕生,它將匯集整個業(yè)界的智慧,融合已有開源框架的優(yōu)秀特性,并使商業(yè)軟件或開源軟件迅速向其靠攏。而它,就是Java EE 5.0!
Java EE 5.0新特性介紹
? ? ?Annotation
Annotation中文意為標(biāo)注,是JDK 1.5中引入的非常迷人的特性之一,通過在Java代碼加入元信息(Meta Data),影響工具和庫對代碼的處理。在Java EE 5中,增加了在POJO(Plain Old Java Object)中進行Annotation功能。Annotation可以用于:
? ? ?定義和使用Web Service
? ? ?開發(fā)EJB組件
? ? ?映射Java類到XML
? ? ?映射Java類到DB
? ? ?指定外部依賴
? ? ?指定部署信息,包括安全屬性等
有了Annotation,XML部署描述符不再是必須的,應(yīng)用的打包從而變得簡單起來,如我們熟知的WAR應(yīng)用中的WEB-INF/web.xml將不再需要,部署信息通過Annotation進行表述,應(yīng)用部署更加靈活。
下面是Java EE 5中使用Annotation定義Web Service的一個例子:
package endpoint;
import javax.jws.WebService;
@WebService
public class Hello {
? ?public String sayHello(String param) {
? ? ? ?return “Hello “ + param;
? ?}
}
一個普通的Java類,通過加入@WebService這一Annotation,服務(wù)器就可將此類中的公共方法發(fā)布為Web Service,簡單又方便。
引入Annotations可以大大降低Java EE開發(fā)成本,開發(fā)更適應(yīng)中小型系統(tǒng)的開發(fā),簡化這部分系統(tǒng)開發(fā)步驟。
? ? ?EJB3.0
EJB3.0是對重載的EJB2的批判性思考和揚棄。在EJB3.0中,不再需要EJB home接口,也不需要實現(xiàn)javax.ejb.SessionBean接口,一個簡單的POJO對象就足于代表實體對象,并支持繼承和多態(tài)。同時,困擾人們多年的EJB部署描述符變成可選的。EJB的持久變得更加簡化、輕量級,EJB的查找也變得更加簡便,JNDI API不再是必須的。EJB3.0還使用了Interceptor,在業(yè)務(wù)方法被調(diào)用前進行攔截,因而更加容易實現(xiàn)靈活的AOP編程。
? ? ?JavaServer Faces 1.2
JavaServer Faces (JSF) 是一種用于構(gòu)建 Web 應(yīng)用程序的新標(biāo)準(zhǔn) Java 框架。它提供了一種以組件為中心來開發(fā) Java Web 用戶界面的方法,從而簡化了開發(fā)。JSF提供了標(biāo)準(zhǔn)的編程接口、豐富可擴展的UI組件庫、事件驅(qū)動模型等一套完整的Web應(yīng)用框架。通過 JSF ,可以在頁面中輕松自如地使用 WEB 組件、捕獲用戶行為所產(chǎn)生的事件、執(zhí)行驗證、建立頁面導(dǎo)航等。JSF1.2支持
? ? ?托管Bean中的依賴注入
? ? ?簡單易用,功能強大,支持?jǐn)U展的表達(dá)式語言
? ? ?大量的JSF組件
? ? ?支持AJAX
? ? ?JAX-WS2.0, JAXB2.0:更簡單、更廣泛的Web Service支持
Java EE 5提供了更簡單、更廣泛的Web Service支持,包括:
? ? ?JSR 224, Java API for XML-Based Web Services (JAX-WS) 2.0
? ? ?JSR 222, Java Architecture for XML Binding (JAXB) 2.0
? ? ?JSR 181, Web Services Metadata for the Java Platform 2.0
? ? ?SOAP with Attachments API for Java (SAAJ) 1.3
JAX-WS 2.0繼承自JAX-RPC 1.1,實現(xiàn)更簡單的編程模型并集成JAXB 2.0,支持可擴展的傳輸協(xié)議,支持支持異步客戶端,并支持REST應(yīng)用。
JAXB2.0全面支持XML Schema,能夠綁定Java類到XML Schema,支持更小的內(nèi)存占用和更快的編組(marshalling)、更靈活的編出(unmarshalling),支持局部綁定 XML文檔到 JAXB 對象。
一個基于JAX-WS 2.0的HelloWorld例子如下:
package endpoint;
import javax.jws.WebService;
import javax.jws.WebMethod;
@WebService() ?
public class HelloWorld{
? //the implementation class must have a default public constructor
? public HelloWorld() {};
? @WebMethod(operationName="sayHello", action="urn:SayHello")
? public String sayHello(String name){
? ? ? ? return "Hello "+ name + "!";
? }
}
上例中,只需要一個實現(xiàn)類,并通過使用annotations,將自動生成SEI和其他一些文件,開發(fā)人員從此可以將精力集中在業(yè)務(wù)邏輯的實現(xiàn)上。
? ? ?依賴注入
通過依賴注入更容易訪問資源。可注入的資源包括:
? ? ?SessionContext
? ? ?DataSources
? ? ?Other EJB
? ? ?Web services,
? ? ?message queues等
一個依賴注入的例子:
package com.example;
@Session
public class MyEJB {
@Resource(name = “employeeDatabase”)
private DataSource myDS;
...
}
上述代碼片斷定義了名為MyEJB的Session Bean,并定義了一個名為employeeDatabase的資源,將其注入到一個名為myDS的字段。通過依賴注入,不再需要復(fù)雜的部署描述符入口,事情就這么簡單。
? ? ?輕量級Java持久API模型
Java 持久API(JPA) 也是Java EE 5中的一大亮點,這是個輕量級的持久模型。
在JPA中,實體是 POJO對象。實體對象不再是組件,也不再需要位于 EJB 模塊中。 另外,對象關(guān)系映射的處理方式也得以標(biāo)準(zhǔn)化,可以通過使用標(biāo)注來指定對象關(guān)系映射信息,同時向下兼容 XML 描述符。
在JPA中,支持命名查詢,通過元數(shù)據(jù)表示的靜態(tài)查詢。重用查詢變得非常簡單。
JPA支持簡單的打包規(guī)則。由于實體 Bean 是簡單的 Java 技術(shù)類,因此幾乎可以在 Java EE 應(yīng)用程序中的任意位置將其打包。例如,實體 Bean 可以是 EJB JAR、應(yīng)用程序客戶端 JAR、WEB-INF/lib、WEB-INF/classes 的一部分。
JPA支持分離的實體。由于實體 Bean 是 POJO,因此可以對它們執(zhí)行序列化,通過網(wǎng)絡(luò)將其發(fā)送到其他地址空間,并在不識別持久性的環(huán)境中使用它們。
JPA提供EntityManager API??梢酝ㄟ^標(biāo)準(zhǔn) EntityManager API 來執(zhí)行涉及實體的創(chuàng)建、讀取、更新和刪除 (Create Read Update Delete, CRUD) 操作。通過EntityManager API,編程將變得非常簡便。
? ? ?泛型(Generics)
Jav EE 5之前一個集合可以放任何類型的對象,相應(yīng)地從集合里面拿對象的時候我們也不得不對他們進行強制得類型轉(zhuǎn)換。
現(xiàn)在Java EE 5引入了泛型,它允許指定集合里元素的類型,這樣你可以得到強類型在編譯時刻進行類型檢查的好處,發(fā)現(xiàn)類型不符,避免到運行時出現(xiàn)類型轉(zhuǎn)換錯誤,不再需要顯式的強制轉(zhuǎn)換(cast)。
舉例如下:
使用泛型前:
ArrayList list = new ArrayList();
list.add(0, new Integer(42));
int total = ((Integer)list.get(0)).intValue();
使用泛型后:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(0, new Integer(42));
int total = list.get(0).intValue();
? ? ?自動裝箱(Autoboxing)和自動拆箱(Auto-Unboxing)
Jav EE 5之前,集合不能存放基本類型,簡單數(shù)據(jù)類型(int,long,float等)和其對應(yīng)的包裝類型(Integer,Long,F(xiàn)loat等)之間不能自動轉(zhuǎn)換。
現(xiàn)在自動轉(zhuǎn)換機制(自動裝箱(Autoboxing)和自動拆箱(Auto-unboxing))解決了這些問題。自動裝箱(Autoboxing)特性讓Java自動包裝一個簡單數(shù)據(jù)類型(例如int)到對應(yīng)的包裝類型中(例如Integer)中。自動拆箱(Auto-unboxing)是相反的過程,即將一個包裝類型(例如Integer)自動轉(zhuǎn)換為它所對應(yīng)的簡單數(shù)據(jù)類型(例如int)。
舉例如下:
以前:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(0, new Integer(42));
int total = (list.get(0)).intValue();
以后(請對照泛型部分使用泛型前的例子代碼):
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(0, 42);
int total = list.get(0);
? ? ?枚舉(Enumeration)
Jav EE 5之前,枚舉類型沒有加入到Java中來,導(dǎo)致我們在程序中寫了許多public static final。
現(xiàn)在加入了一個全新類型的“類”-枚舉類型。本質(zhì)上,一個枚舉是一個命名常量的列表。枚舉類型通過新的關(guān)鍵字enum來支持。下面是定義一個枚舉的例子代碼:
public enum Color
{
Red,
White,
Blue
}
然后可以這樣來使用Color myColor = Color.Red.
枚舉類型還提供了兩個有用的靜態(tài)方法values()和valueOf(). 我們可以很方便地
使用它們,例如
for (Color c : Color.values())了System.out.println(c);
? ? ?增強的for循環(huán)
Java 5.0中添加了“For-Each”形式的循環(huán)。For-Each循環(huán)的加入簡化了集合的遍歷,為大量集合、數(shù)組等的循環(huán)處理提供了便利,并為我們防止數(shù)組越界提供有益的幫助,還避免了原來必需的強制類型轉(zhuǎn)換(case),讓我們能在編譯時就發(fā)現(xiàn)類型不符,避免到運行時出現(xiàn)類型轉(zhuǎn)換錯誤。
假設(shè)我們要遍歷一個集合對其中的元素進行一些處理。典型的代碼為:
void processAll(Collection c){
for(Iterator i=c.iterator(); i.hasNext();){
MyClass myObject = (MyClass)i.next();
myObject.process();
}
}
使用For-Each循環(huán),我們可以把代碼改寫成:
void processAll(Collection c){
for (MyClass myObject :c)
myObject.process();
}
這段代碼要比上面清晰許多,并且避免了強制類型轉(zhuǎn)換。
? ? ?不定參數(shù)(Varargs)
Varargs使程序員可以聲明一個接受可變數(shù)目參數(shù)的方法。在過去,經(jīng)常采用將參數(shù)包裝到一個數(shù)組或者集合中的方式。Varargs讓一個方法可以帶有可變數(shù)目參數(shù)。Varargs的加入使得創(chuàng)建帶有可變數(shù)目參數(shù)的方法變的更加容易。下面是使用不定參數(shù)的例子:
// 方法定義
void argtest(Object ... args) {
? ? for (int i=0;i <args.length; i++) {
? ? }
}
// 調(diào)用方式
argtest("test", "data");
? ? ?靜態(tài)導(dǎo)入(Static Import)
過去使用靜態(tài)成員通常我們需要進行這種形式的調(diào)用:YourClassName.staticMember,在每次使用靜態(tài)成員的時候我們都要把這個靜態(tài)成員所屬類的名字寫一遍?,F(xiàn)在靜態(tài)導(dǎo)入可以讓我們不必每次都去寫類的名字了,可以直接通過靜態(tài)成員的名字來訪問它們,無需再給出他們的類名。下面是使用靜態(tài)導(dǎo)入的例子:
// 靜態(tài)導(dǎo)入
import static java.awt.BorderLayout.*;
// 調(diào)用靜態(tài)成員
getContentPane().add(new JPanel(), CENTER);
? ? ?元數(shù)據(jù)(Metadata)
新的元數(shù)據(jù)工具更多是為未來考慮而增加的,它讓你能夠在程序中嵌入注解(annotation),這些注解能夠被不同的編程工具處理。例如,工具可以根據(jù)注解(annotation)的要求生成Java源代碼,這樣只要程序員指定一種動作,然后就可以將實際提供代碼的事情留給工具了,從而大大降低了程序員必須手工輸入的重復(fù)代碼的數(shù)量。
下面是使用元數(shù)據(jù)前后的代碼對比:
使用前:
public interface PingIF extends Remote {
? ? public void ping() throws RemoteException;
}
public class Ping implements PingIF {
? public void ping() {
? ? ? ……
? }
}
使用后:
public class Ping {
? public @remote void ping() {
? ? ? ……
? }
}
? ? ?其它改變
Java 5在基礎(chǔ)類庫、用戶界面、虛擬機、執(zhí)行效率、垃圾收集等其它方面也進行了大量的升級。
jwebee
我的個人網(wǎng)站