今天TSS和InfoQ都转了一篇Spring与EJB3的读后感,我就看了下,标题和介绍满吸引人的。内容嘛其实有点不过瘾,但是先记录下来吧。
http://www.devx.com/Java/Article/32314/0/page/1总的来看Spring+Hibernate与JPA很相似,它们都是基于pojo的持久化。
Hibernate Session和JPA Entity Manager基本上等价,但是要记住他们的两个重要区别。Hibernate session是一个实体缓存也是一个ORM引擎的接口。而JPA中这两个概念是分开的。Persistence context作为缓存而entity manager则作为ORM引擎的接口。
当然还有显而易见的区别,Spring+Hibernate偏向使用XML配置映射,而JPA偏向使用Annotation,虽然两者都有XML和注释两种实现。
还有,JPA是一个标准,而Spring是对不同实现的抽象,两者的方向是不同的。JPA的方式更彻底,Java传统中都是这样的。
JPA的主要商业实现有Hibernate、Kodo、Toplink,被巨鳄们看好。
后面,说到了关于Cache和Transaction管理的问题,由于Spring的草根特性,为了兼容实现,它使用Tread local这种编程式的方式。而EJB 3.0则由容器自动完成这些过程。而且EJB 3.0提供了不同的persistence context范畴,可以比较方便的管理持久数据的生命周期。不过,这个观点很难说,因为如果你把Spring也看成一种容器,那么这Thread local对于你来说也是透明的,可以认为差不多。
关于EJB 3.0对生命周期的规定,让持久化的概念更清楚了,如果这些东西能够通过声明而不是编码来实现应该是惬意的,可是,问题就是很多程序员一般就喜欢自己控制,不喜欢那么透明,所以EJB一直以来兴建的这些漂亮模型总是只有少数人使用,不是么?
在事务方面,由于两者都支持生命性事务,所以程序本身看起来基本一样。
区别在于配置。Spring还是偏向XML,并且事务作为Spring对AOP应用的经典样例,transaction完全作为附加语义,可以通过配置替换各种事务实现,从JDBC、Hibernate到JTA,显然这是从编程者角度考虑的,门槛很低。
而EJB 3.0则只支持JTA,这就需要容器的支持,当然跨多资源的事务往往是企业级项目的特性,所以这种思路可以理解。而且现在也有很多开源的JTA实现了,它们完全可以让你的应用在商业EJB容器外运行。还要提一点,EJB3默认是配置上事务的,需要声明才可覆盖,这说明了EJB3对于企业应用的态度。
在JTA事务可以通过声明就以横切关注点的形势注入的时候,JTA的成本已经下降了,所以一开始就用这种API完全可行。
这篇文章中关于状态的地方我有点不太理解,里面说Spring的prototype等价于EJB的SFSBs,实现stateful。
EJB 3.0在这方面无疑是强大的,因为本身在这方面它就是个容器规范,Java EE容器都会提供这种高级的生命周期管理,并且把生命周期作为变成模型中非常重要的一部分。所以结果就是EJB 3.0在这方面领先于Spring,声名简单,并且从实现的方式上来说,EJB 3.0在性能上和可伸缩性上有明显的优势。Spring在性能伸缩或者说分布部署的时候应该说是捉襟见肘的,Terracotta也许可以解决些,但还……
应该说,实际上Spring提供的prototype就是new的另外一种实现,只不过它会经过Spring装配,所以它叫做prototype,也就是“原型”,Spring每次回new出一个新的,按你的要求。当然,由于是类似new,所以Spring通过代理的方式管理起生命周期,也就能模拟出session、request、global session的statefull,不过这些功能显然不算强项,在Spring 2.0中加强了(以前只有singleton和prototype),但依然不支持事务范畴,这就明显不如EJB 3.0了。但是,回想Spring的编程哲学,它不要解决这种问题,这种问题留给容器解决:D
文章最后的总结比较官腔,基本上就是在说Spring灵活,EJB 3.0强大简单,它们各有优缺点,所以应该结合起来使用,具体大家可以看看原文。