文本继续和大家分享EJB3.1特性,今天谈到的EJB Lite我个人感觉更像是Spring的子集.至于首先谈到的异步Session Bean调用,到底是消息驱动Bean的替代品还是补充,更需要更进一步的信息,废话不多说了,开始吧.
原文请看:http://www.theserverside.com/tt/articles/article.tss?l=NewFeaturesEJB31-3
讨论
该系列文章预先给大家介绍了专家组们正在继续研究JavaEE下一版本的规范——EJB3.1所带来的改变。理想情况下,文章提到的这些变化,希望可以尽早的从你那里得到反馈从而使得专家组可以做出最好的选择。EJB3.0已经将笨重的JavaEE编程模型转变得简洁明了。EJB3.1的目标就是在此基础上通过添加一系列必须的特性,使得EJB走的更远。在应系列的每一篇文章中,我将告诉你专家组的进展情况。
本系列的前两篇文章已经谈到一些特性包括:可选的Session Beans接口,增强的EJB Timer Service以及简化后的打包机制。本文作为EJB3.1的第三部分,将涉及两个新特性:asynchronous Session Bean invocation(异步Session Bean调用) 和 EJB Lite。不过请记住,这一切还没有最终敲定,JCP成员还只是刚刚提出这些特性,所以如果必要的话,你可以反馈给我们。
最初草案已经公开了
EJB3.1规范的草案已经两个星期前就发布了,你可以通过http://jcp.org/aboutJava/communityprocess/edr/jsr318/index.html来获得相关信息。也许你已经知道,草案囊括的是整个规模,并仅仅是新加入的这些特性,但不要泄气,跳过原有的EJB3.0部分并不十分困难。注意,草案并不等同于最后的规范,还需继续完善,并提交给供应商们,让他们实现自己的产品,所以从开发人员的角度来看,可读性稍稍有点困难。希望你能一如既往的将你的想法和建议反馈给EJB3.1专家组,邮箱是[email protected]。当然,可以直接发给我个人邮箱:[email protected]。
异步Session Beans调用
令人惊讶的是,对于许多企业应用程序来说,异步处理实际上是一个普通的需求。大多数案例比如说使用fire-and-forget 模式[注1]来后台处理一些长任务(或长事务)时,一方面尽量使得用户接口易于接受和使用,另一方面还可以通过简单通过利用并行计算来增强应用程序。最早的JavaEE实现就是今天我们所使用的消息驱动Beans(Message Driven Beans)。实际上,在《EJB3 in Action》一书中第一个消息驱动Beans实例,用于实现一个异步订单功能。更进一步的说, 在客户确认订单后,消息驱动Beans OrderBillingMDS异步的给客户开出账单.并且当支持结果完成后(无论是支持成功还是失败),更新订单信息.请看下面的图1:
图1:异步订单支付
虽然消息驱动Beans的确可以进行异步处理,同样又要求你处理JMS以及一些其它相关功能。而现在,这一切刚好可以通过调用我们的异步Session Beans来解决,随着Session bean的增强,你可以简单的使用@Asynchronouse来标注你的session bean方法,使其具备异步处理特性。现在我们再看看《EJB in Action》中那个改进后的异步订单支付实例:
@Stateless public class OrderBillingServiceBean implements OrderBillingService { ... @Asynchronous public void billOrder(Order order) { try { // Attempt to charge the order. bill(order); // Send email notification of billing success. notifyBillingSuccess(order); order.setStatus(OrderStatus.COMPLETE); } catch (BillingException be) { // Send email notification of billing failure. notifyBillingFailure(be, order); order.setStatus(OrderStatus.BILLING_FAILED); } finally { update(order); } } ... }
由于使用了@Asynchronous标注,当客户端调用OrderBillingService.billOrder()方法时,调用会立即返回,而不会一直阻塞,直到billOrder方法执行完毕后才正常退出应该方法。EJB容器会去确认哪些方法需要同步执行.或许你已经注意到了,异步方法的返回值是void型的,或许对于绝大多数异步Session Bean方法来说,这已经足够了.不过,EJB3.1还支持java.util.concurrent.Future<V>作为返回类型,其中V表示异步调用后,返回结果的类型.万一你不熟悉异步的话,Future<V>接口允许你做以下几类事:
l 取消异步调用
l 检查调用是否运行结束
l 查检是否有异常
l 得到异步调用后的结果
想了解关于Future<V>接口更多细节,请看http://java.sun.com/javase/6/docs/api/java/util/concurrent/Future.html
现在我们来一个使用Future<V>作为返回类型的实例.在上文提到的billOrder方法中,我们设置了order(订单)实体的状态值,并且对其进行更新操作.现在假设调用者自己想知道order的支付状态值是什么,我们可以重构上述代码如下:
@Stateless public class OrderBillingServiceBean implements OrderBillingService { ... @Asynchronous public Future<OrderStatus> billOrder(Order order) { try { // Attempt to charge the order. bill(order); // Send email notification of billing success. notifyBillingSuccess(order); return new AsyncResult<OrderStatus>(OrderStatus.COMPLETE); } catch (BillingException be) { // Send email notification of billing failure. notifyBillingFailure(be, order); return new AsyncResult<OrderStatus> (OrderStatus.BILLING_FAILED); } } ... }
javax.ejb.AsyncResult<V>实现了Future<V>接口,并且将异步调用后的结果值作为其构造函数的参数.尽管如此,没有人可以阻止你去实现Future<V>接口.异步调用来支持一些其它优雅的特性,比如说保证传输安全性和事务性等等.更多详细内容,可以参看草案.
你怎么看待异步Session Bean调用特性?我个人觉得这很酷,你觉得还有必须增加其它特性吗?
EJB Lite简介
许多人抱怨EJB和JavaEE的一个主要原因在于:它通常提供的是一个激进的解决方案,恨不得任何人都去尝试EJB的所有特性.事实上,我们应该理解JavaEE只是一个平台,必须具备全面性与普遍性,但实际开发并不一定要遵循这个原则.JavaEE6的Profiles已经反射出了一些问题.Roberto Chinnici,作为JavaEE6规范的领导人,已经在他的blog发表了关于JavaEE6的文章:http://weblogs.java.net/blog/robc/archive/2008/02/profiles_in_the_1.html.简而言之,Profiles所定义的JavaEE的子集适用于特殊目的,比如说,最低要求的Web Profile已经向非常简单的Web应用程序迈进了.
尤其当我们聚焦于EJB时,典型的web项目基本上不太可能使用remoting(远程调用),EJB Timer Service 以及 Message Driven Beans.实际上,大部分EJB应用程序都是简单的利用注入,持久层管理,sateless session bean以及声明式事务处理等.EJB Lite正是试图紧跟上述需求,做到尽可能的减少EJB多于的特性.从一方面来说,有了EJB Lite是一个简单并且轻量级的实现;从另一方面来说,学习EJB Lite就意味着你只需要学习一些annotations,甚至如何配置都没有必要.下一代的JavaEE应用程序服务器很可能情愿实现EJB Lite,而不是EJB3.1的规范.比如说,如果EJB Lite成为事实,那么Spring很可能会紧随其原有的Pitchfork项目,实现EJB Lite. (注意: Pitchfork由SpringSoruce和BEA联合发起,实现JavaEE5.0一个子集的项目.原文用的还是Interface21,我在这里改成SpringSoruce,以免大家产生误解.当我看到这里时,我第一反应,Reza Rahman不遗余力的力挺EJB Lite,很显然害怕因SpringSource和BEA的联手实现的Pitchfork再次成为新EJB子标准,从而再次陷入被动,即使不是Pitchfork,那么出现别的EJB子集,专家组也不好受,毕竟多年不停的被别人牵着走的日子不好过啊.)
当前EJB Lite被提及的特性如下:
l 包括Stateless Session Beans, Stateful Session Beans 以及 Singleton Session Beans.
l 只有本地EJB接口,或者根本就不要
l 不支持异步调用(你们觉得有必要加吗?)
l 拦截器功能
l 可声明式安全特性
l 可声明式或编程式的事务处理.
(注:天啊,如果用过Spring的话,相信上述特性一定不会陌生.难道EJB Lite的真正领导人是Rod Johnson)
你是怎么看待这个列表的?还应该再减少些什么吗?或者有什么东西还需要加入其中?你觉得你的应用程序最重要的是什么?作为一个参考,下面的表格对EJB和EJB Lite进行比较:
Feature | EJB Lite | EJB |
Stateless beans | Y | Y |
Stateful beans | Y | Y |
Singleton beans | Y | Y |
Message driven beans | Y | |
No interfaces | Y | Y |
Local interfaces | Y | Y |
Remote interfaces | Y | |
Web service interfaces | Y | |
Asynchronous invocation | Y | |
Interceptors | Y | Y |
Declarative security | Y | Y |
Declarative transactions | Y | Y |
Programmatic transactions | Y | Y |
Timer service | Y | |
EJB 2.x support | Y | |
CORBA interoperability | Y | |
哪些特性还在日程上
到现在为止,我已经为大家一一介绍了Singleton beans, 可选的Session Beans接口,Timer Service, 简化后的EJB打包机制,异步Session Bean调用以及EJB Lite.但仍然还有很多特性没有提到,专家组还在为这些特性进行激烈的讨论:
l 通过Stateful Session Bean 的 web service endpoints 支持Stateful web service.
l 标准统一的JNDI映射机构,而并不让各个供应商自己决定
l 支持JavaSE环境也能运行EJB3.1,这样做的的一个最直接目的就是方便单元测试.
你是怎么看待这些特性的?如果你觉得它们很重要,请大胆发表你的意见,并给专家组发Email.还有什么特性你想了解?你现在对这些特性的情况的了解是否现在越来越清晰了呢?我还会继承跟进本系列文章的.很多人提出,关于EJB和WebBeans整合,还有WebBeans提供的enhanced DI(依赖注入)特性也要介绍一下.到时候,我会介绍的,今天就至此为止,再见我的朋友们.
注1: Fire-and-forget来源于军事术语,其含义是指某些武器(比如一些导弹)当被发射出去之后就能够自行攻击目标,发射者无需再提供控制。而在消息的应用模式中, Fire-and-forget是指发出消息后,不再去处理与该消息相关的操作。