EJB3,我们究竟得到了什么 (2)

<二>皇帝的新装 
        JSR220规范书由三个部分组成:EJB 3.0 Simplified API,EJB Core Contracts and Requirements和Persistence API。在Persistence API规范书里,可以发现,EJB翻天覆地的变化是在它的持久方案上。一个所谓"透明持久方案",一个ORM的引擎。这里,我们会很容易想到Hibernate这个大名鼎鼎的ORM框架,确实,Gavin King是这次JCP专家组的成员之一,而且率先写了JSR220持久API的第一笔,这一笔何其重要,它的命名方式让我们隐约感到Hibernate的气息。但是它并非Hibernate,专家组中还有JDO和Toplink的影子。持久方案是目前流行的ORM方案的一个缩影。在这里我不得不鄙夷地填上一句:JSR220没有任何的原创思想,所有的东西都来自一些成功的Open Source项目,包括一些轻量级容器。我在下面会列举它们。
        让我们看看EJB3所承诺的:

        1.Annotation
用Metadata来描述配置,并不是EJB3的创举,我们不会忘记Xdoclet,加上这些@的好处是,你可以免去看密密麻麻的XML代码,很多配置可以在实时完成,而且,规范书一再强调使用Annotation是根据configuration of Exception原则,也就是开发者可以不加annotation,EJB的容器会用预定的初始配置来解释。这使得我想起Rubby on Rails鼓吹的Convention over Configuration原则。它们应该是一回事吧,我再次地讨厌起那些玩弄概念的人,在我的脑袋里硬塞了这么多重复的故弄玄虚的名词。这些概念的炒作并不能解除我对某些事物困惑,它们只会让人又多了一份更"抽象的困惑"。
        确实,Annotaition会让我们配置EJB变得轻松,但是,我们的代码也变得史无前例的丑陋,加满了Annotation的EJB代码就好比一根赤豆棒冰,怎么能和有光滑肌肤的牛奶棒冰相比。在JSR220所规定的Annotation之外,还有很多Annotation的扩展可以使用,例如,Hibernate Validator,JBoss EJB3等,当然,开发者还可以定义自己的Annotation,因为EJB3是运行在JDk1.5上的。。。我们是不是将面对一个annotation泛滥的世界。
       JSR220说EJB3和老的EJB兼容的,这有两层意思,首先,我们还可以用DD来配置,可以和annotation的配置方法混用。再者,EJB3和EJB2.1的组件可以协同工作。

       2.POJO/POJI
EJB3都是POJO是谎言,MDB不是,它还是需要执行特定接口,怎么是POJO。还有,加了annotation的java class是POJO?Plain old java object是没有meta data的,而且我们需要库来解释annotation。离开这些库,错误信息会象飘雪。POJI的支持主要是可以免去一些接口,并且可以不用写恼人的call back函数。自定义的生命周期函数,可以是任意的,通过annotation来标注。如果POJO/POJI最大的贡献是能让我们以面向对象的思维来写java Bean的话,另一个优点是它便于(TDD)Test Driven Development,也就是,在容器内测试和在容器外测试。对EJB来讲在容器内测试不是什么新鲜事,新鲜的是在容器外测试。在TSS(The server side)网站上有几个容器外测试的例子,但我觉得它们不值得被煞有其事地写成文章。因为它们在轻型容器中实在太普通了。而我们却为EJB里这么个迟到的进步感激涕零。对大多数的SB和MDB测试,我们仍然需要容器,即使容器可以象库一样挂在那里,例如在用JBoss MicroContainer和TestNG测试,但是它仍然需要容器来支持它所管理的部分,例如如果使用了CMT。

       3.依赖注射(DI)
Martin Fowler是个成功的概念炒作手,就象华尔街金融炒作手一样,有化腐朽为神奇的本领。在他书中揭示的结构,花式被广泛地传诵在任何一个写JAVA程序的人嘴上。就象他写的IoC白皮书之后,依赖注射一度成为最时髦的技术用语,就象冯小刚电影里的对白,泛滥得连刚会写JAVA的人也会来上这么一句。但是依赖注射真的那么神吗?首先,依赖注射在EJB2.x中不是没有,想想我们怎么得到SessionContext,怎么得到EJBContext...?我们没有注意,我们注意的是JNDI的Lookup。依赖注射只是一个IoC的执行,仅此而已,它的好处是代码不再这么依赖它的环境,再次用个概念用语"松耦合"。(一个经常提的抽象概念,我赞成用一个简短的名词来代替,但是往往这些词让人摸不着头脑,譬如对耦合,怎么个程度算松算紧。可能我是极少数坦白这个事实的人,因为这样的承认经常被认为是没有水平的,而动不动无数个概念名词出口的被认为是专家。幸好我并不热衷做这样的"专家")Martin Fowler在阐明Service Locator和DI区别的时候做了这么个比喻,DI好比是通知环境准备好它所要的资源,而不是直接要。EJB3容器将保证这种获得所需要组件的方式,当然通过Annotation,以Setter的方式进行注射。例如只需放@EJB,@Resource在属性声明的上面,就可以完成注射,容器会根据情况初始化一个或分配一个所需的资源。有些常用的资源例如Timer都不需要加Annotation,它会在使用的时候自动的分配进来。DI只能用在EJB的容器里。超出了这个容器,我们仍然需要JNDI lookup,值得高兴的是,这回lookup可以直接用接口名便可以得到要找的资源,而不是一大串JNDI注册名。
       DI真的这么重要吗?我说,DI是使EJB POJO化的一个因素,因为使用DI我们可以避免写和环境有关的代码,例如JNDI lookup。也使得我们的代码变得清爽易读,应用构架会更加的清晰。。。但DI不是什么新技术,它仅仅是一种资源分配的方式,是简化开发的一种办法,如果谁觉得用Service Locator花式对付EJB2.1也非常清楚简单,那么他完全可以忘记DI。

       4.Interceptor
Sevlet Filter是interceptor花式的执行,但是EJB没有,可能以前JCP专家组认为有call back函数就够了,但是在这个被AOP冲击的年代里,不说几句join point拉,cross cutting concern拉,似乎会被认为落伍。EJB3的新玩意儿Interceptor似乎带了点AOP时尚的气息。但是,在我看来它弄得不巧,变成了很古怪的东西。首先,我们需要用annotation明确的写在代码,告诉容器我们要用interceptor但是一个AOP怎么会允许去修改原来的程序代码呢?其次,一个Bean可以声明作Interceptor类,好比说一个Bean可以做一个Aspect...看来,这么一种古怪的"AOP"方式需要时间去适应。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页