我们为什么需要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
周行 阅读(313)
评论(0) 编辑 收藏 所属分类:
IT技术