爱因斯坦曾经说过:"每件事物都应该尽可能简单,而不是更简单"。的确,对科学真理的追求都是为了简化理论的根本假设,这样我们才能处理真正麻烦的问题。企业级软件的开发也是这样的。
简化企业级软件开发的要害是提供一个隐藏了复杂性(例如事务、安全性和永续性)的应用框架。良好设计的框架组件可以提升代码的重复使用(reuse)能力,提高开发效率,从而得到更好的软件质量。但是,目前J2EE 1.4中的EJB 2.1框架组件被人们普遍认为是设计较差的和过于复杂的。Java开发者对EJB 2.1很不满,他们已经试验了多种其它的用于中间件服务传送的方法。最引人注目的,下面两个框架组件已经引起开发者的巨大爱好和积极的反映。它们很可能成为未来企业级Java应用程序可供选择的框架组件。
· Spring框架组件是一个流行的,但是非标准的开放源代码框架组件。它主要是由Interface21 Inc.公司开发和控制的。Spring框架组件的架构是基于依靠注入(DI)设计模式的。Spring可以单独地或者与现有的应用程序服务器一起工作,它大量地使用XML配置文件。
· EJB 3.0框架组件是一个标准的框架组件,由Java社区组织(JCP)定义,并受到所有主流的J2EE厂商支持。预发布的EJB 3.0规范的开放源代码和商业实现都可以在JBoss和Oracle上看到了。EJB 3.0大量使用Java注释(annotation)。
这两个框架组件的核心设计理念是相同的:两者的目标都是把中间件服务传递给松散耦合的简单旧式Java对象(POJO)。这些框架组件通过在运行时截取执行内容或向POJO注入服务对象,把应用程序服务与POJO捆绑在一起。POJO本身不关心捆绑的过程,并且对框架组件几乎没有依靠。其结果是,开发者可以聚焦于业务逻辑,个人可以在没有框架组件的情况下测试他们的POJO。此外,由于POJO不需要从框架组件中继续或实现框架组件接口,开发者建立继续结构和构建应用程序的时候都有高度的灵活性。
但是,尽管两者的设计理念是相同的,它们传递POJO服务时却采用了完全不同的方法。尽管目前已经出版了大量的图书和文章来把Spring或EJB 3.0与EJB 2.1进行对比,但是它们都没有对Spring与EJB 3.0之间的差异进行认真的研究。在本文中,我将研究Spring和EJB 3.0框架组件之间的要害差异,并讨论它们的优缺点。本文的主题也可以应用在其它一些名气稍小的企业级中间件框架组件上,因为它们都聚焦于"松散耦合的POJO"设计。我希望本文能够帮助你选择符合需求的最佳的框架组件。
厂商无关性(Independence)
开发者选择某种Java平台的一个最重要的理由就是该平台的厂商无关性。EJB 3.0是一个开放的、标准的、具有厂商无关性的平台。EJB 3.0规范是由企业级Java团体中所有主流开放源代码和商业厂商开发和支持的。EJB 3.0框架组件把开发人员与应用程序服务器实现(implementation)隔离开来了。例如,尽管JBoss的EJB 3.0实现是基于Hibernate的,而Oracle的EJB 3.0实现是基于TopLink的,但是开发人员并不需要学习Hibernate或TopLink的非凡API,就可以让他们的应用程序在JBoss和Oracle上运行。厂商无关性把EJB 3.0框架组件与其它的POJO中间件框架组件区分开来了。
但是,很多EJB 3.0的批评家迅速指出,在写这篇文章的时候,EJB 3.0规范还没有达到最终发表的版本。在EJB 3.0被所有主流的J2EE厂商采用之前可能还需要一到两年时间。但是,即使你的应用程序服务器还没有自然地(natively)支持EJB 3.0,你还是可以通过下载和安装一个"嵌入式的" EJB 3.0产品,在服务器上运行EJB 3.0应用程序。例如,JBoss嵌入式EJB 3.0产品是开放源代码的,可以在任何与J2SE-5.0兼容的环境中(例如,在Java应用程序服务器中)运行。它现在正在进行beta测试。其它的厂商也可能很快发布他们的嵌入式EJB 3.0产品,非凡是用于规范的"数据永续性"部分的产品。
另一方面,Spring一直是非标准的技术,而且在可以预见的未来它仍然是这样的。尽管你可以把Spring框架组件与任何应用程序服务器一起使用,但是Spring应用程序都被"锁定"在Spring自身和你所选择的集成到Spring中的特定服务中了。
· 尽管Spring框架组件是一个开放源代码项目,但是它仍然拥有配置文件的专利XML格式和专利编程接口。当然,这类"锁定"发生在任何非标准的产品上,Spring也不例外。但是它却造成了:你的Spring应用程序的长期生存能力依靠于Spring项目本身(或Interface21 Inc公司,它雇佣了大多数Spring核心开放人员)。此外,假如你使用任何Spring特定的服务,例如Spring事务治理器或Spring MVC,你就被"锁定"在这些API中了。
· Spring应用程序需要知道后台的服务提供者。例如,对于数据持续(data persistence)服务来说,Spring框架组件为JDBC、Hibernate、iBatis和JDO使用了不同的DAO和模板辅助类。因此,假如你希望为Spring应用程序更换持续服务提供者(例如从JDBC切换到Hibernate),你就必须重构自己的应用程序代码,使用新的辅助类。