技术的离心力
考察事物的演化,通常有两种对立的方法。考古学家(Archaeologist)探究肇始和起源;目的论者(Teleologist)则揭示目的和终点。对于前者,“开端(希腊语Arche)”从根本上决定了此后的发展,参天大树的繁茂都包含在种子最初的萌芽中;而对于后者,“目的(Telos)”才是事物的根本和旨归:谁没见过样态完善的树,谁也就没法弄懂种子到底是怎么回事。
在J2EE五年之后,人们只能交替地用这两种目光审视它的演化历程。它的起源与它的目的、“它从何处来”与“它往何处去” 的问题紧密地交织在一起,谁拾起了其中的一个,谁也就要连同另一个一起回答。
今天的J2EE在多大程度上符合它的初衷?回答这个问题并不涉及对J2EE技术成败的评判,而只是要考察一下:它是否还运行在最初开辟的那个空间之中。在事务处理、对象分布化和Web请求处理这三个方面中,也许J2EE对事务和Web保持了一贯的忠诚。我们记得Fleury喜欢重复的一个信条:“He who owns the transactional Web owns the Web(谁掌握了带事务处理的Web,谁就掌握了Web)”Web接口是今天大部分J2EE应用暴露的唯一接口;而虽然事务处理的常用方法已经有了很大改变(借助AOP机制,很多非EJB架构的系统也自如地实现了声明式的事务处理),但对事务的重视当然仍将是J2EE开发中的要素之一。
换言之,在5年的演化中,J2EE发生的最大变化可能就在于它放弃了对“分布式对象模型”的强调。EJB2.0引入的本地接口使得Web层与EJB层可以运行在同一个Java虚拟机中,从而使Web容器与EJB容器的物理分离部署变成一种昂贵的冗余;J2EE 1.4以后版本支持的Web Services兼容性,使得客户端可以通过粗粒度的Web接口调用远程服务——这两次变化事实上都是在论证“分布式对象架构”的无用性。人们发现,同一系统的各个分层最好采用细粒度接口调用,并且运行在同一个进程中;之所以划分不同的层次,与其说是为了实现物理上的可扩展性,不如说是设计美学上的考虑。而对于异质系统之间的调用,则应该尽量选用异步的、粗粒度的服务接口(所以Web Services成为了非常理想的选择)。换句话说,传统上的“分布式对象架构”,现在看来似乎只适合于银行远程支付等要求极为苛刻的应用场景,而绝不是所有J2EE应用都该考虑的标准方案。
前面描述的离心现象毕竟还遵循了J2EE发展的内在逻辑,说到底,EJB的革新和Web Services的引入更多地是主流厂商倡导的结果。但在近年来,还有一股更强劲的离心潮流在深刻地影响着J2EE的演进,它肇始于上文提到的开源软件运动。最初它只在Rickard Oberg的动态代理RMI设计与JBoss服务器的微内核架构中显露过邪恶的一角,但是两三年来,经过多个项目、各种技术杂志/论坛/Blog的折射和放大,它已经形成了一个名为“轻量级容器架构”的完整解决方案,并暴露出完全取代传统EJB架构的终极野心。按照这一运动信徒们的说法,J2EE的发展史上只出现过一个错误——不幸的是,这个错误名叫EJB。与EJB提供的重量级架构不同,借助AOP和IoC机制,轻量级容器能够最大程度地降低代码对于专用接口的依赖性,以简短、轻便、专注、可移植的方式实现业务对象。从“轻量级容器架构”这个词被发明出来的那一刻起,人们对J2EE远景的考虑就发生了根本性的分裂:Sun和大部分主流厂商更多地关注于“Web Services”和“快速开发工具”这些利润增长点,而一部分离经叛道的独立专家和开发者则认为,如果不把轻量级容器纳入规划,J2EE的发展蓝图就注定无足称道。其实,双方争执的关键是传统意义上的“应用服务器