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