`
kyo100900
  • 浏览: 640482 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【翻译】EJB3.1真的来了吗?EJB3.1系列文章(四)

阅读更多

 

前言

 

Raza 同学终于又出 EJB3.1 文章了,真是姗姗来迟,我也是刚翻译出来,希望和大家分享 EJB3.1 的新特性。今天主要讲的是 WebBeans ,相信很多关于 EJB3.1 的人,一定会对它感兴趣的,今天我们谈到 WebBeans 两个方面:依赖注入和增强的拦截器模型。相信今天的文章会让你有所收获。

原文:http://www.theserverside.com/tt/articles/article.tss?l=NewFeaturesinEJB3-Part4

 

 

 

正文

 

WebBeans EJB :如漆似胶

 

 

WebBeans 是当前 JavaEE6 日程安排中最激动人心的 JSRs 规范之一。支持集成 WebBeans 的主张非常有号召力。如果你用过 JSF EJB3.0 来开发应用程序的话, JSF 的那层薄薄 backing bean 一定让你印象深刻。实际上,即使你可以用 @EJB annotation 很容易的将 EJB 注入到 backing bean 的话,那么 backing beans 还是在充当 glue-code 的角色。而 WebBeans 却允许你直接使用 EJB 作为 JSF backing beans ,从而去掉了多余的 glue-code 。在第二小节的时候,我们共同来验证这样的美事吧。

 

 

除了更有效的整合 JSF EJB 编程模型外, WebBeans 当然也少不了提供一系列很酷的特性,包括:

 

<!---->l         <!---->更健壮的基于 annotation 的依赖注入

<!---->l         <!---->越发简洁易用的 JavaEE 拦截器模型

<!---->l         <!---->更加合理的对 Web 应用程序的组件上下文进行管理

 

这里的最后一点我不想多说,因为这里更侧重的是 JSF 而并非 EJB ,但剩下的精彩主题是会一一向大家介绍的。

 

WebBeans 很大程度上受 JBoss Seam Google Guice 的启发。现在该 JSR 规范由 Gaving King Bob Lee 所领导 ( 注:两位绝对是 Java 界响当当的牛人 ) 。我个人觉得,虽然东西到了 JSR 手里肯定会有自己的实现版本,但 Seam 的核心代码仍然是 WebBeans 的基石。

 

 

 

EJB 成为 JSF Backing Beans

 

 

好吧,现在我们从 EJB3 in Action 拿一个例子进行重构,从总体上看看 WebBeans 究竟是什么。在 EJB3 in Action 中,最经典的 Session bean 例子自然还是那个“竞标”例子了 (adding a bid) Session bean 使用了 JPA 将一个 Bid entity( 实体 ) 持久化到数据库。现在我们来看看在 WebBeans 的环境下, session bean entity 变成什么样子了:

 

@Component
@Stateless
@Named("placeBid")
public class PlaceBidBean {
	@PersistenceContext
	private EntityManager entityManager;

      @In
      private Bid bid;

	public void addBid() {
	    entityManager.persist(bid);
	}
}

@Component
@Entity
@Named("bid")
public class Bid {
    private Long bidId;
    private String bidder;
    private String item;
    private Double bidPrice;

    @Id
    @GeneratedValue
    public Long getBidId() {
        return bidId;
    }

    public void setBidId(Long bidId) {
        this.bidId = bidId;
    }

    public String getBidder() {
        return bidder;
    }

    public void setBidder(String bidder) {
        this.bidder = bidder;
    }

    public String getItem() {
        return item;
    }

    public void setItem(String item) {
        this.item = item;
    }

    public Double getBidPrice() {
        return bidPrice;
    }

    public void setBidPrice(Double bidPrice) {
        this.bidPrice = bidPrice;
    }
}

 

 

stateless bean PlaceBidBean Bid JPA entity 使用 @Component annotion ,这样就可以将它们同时注册到通过 WebBeans 容器里去。 @Named annotation 给组件分配的名称可以由 WebBeans 容器识别出来。而这些名称可以直接在 JSF 页面上使用。 ( 注:比如说上面的 @Named(“bid”) 相当于为 Bid 类起了一个别名,这样做的意义在于 JSF 可以用 bid 直接取值了,比如说 #{bid.bidId}, #{bid.bidder} 等,与 Struts2 需要写一大堆 set,get 方式相比,确实精简不少。 ) bid 实例变量上的 @In annoation 是告诉该 session bean bid 是注入进来的。我相信到这里,你应该很清楚在使用 WebBeans 组件后,相应的 JSP 页面代码会是怎么个情况了吧。图一,显示了一个实际竞价页面:

 

<html>
  ...
  <body>
    <f:view>
      ...
      <h:form>
        <table>
          <tr>
            <td>Bidder</td>
            <td><h:inputText value="#{bid.bidder}"/></td>
          </tr>
          <tr>
            <td>Item</td>
            <td><h:inputText value="#{bid.item}"/></td>
          </tr>
          <tr>
            <td>Bid Amount</td>
            <td><h:inputText value="#{bid.bidPrice}"/></td>
          </tr>
        </table>
        ...
        <h:commandButton type="submit" value="Add Bid" 
            action="#{placeBid.addBid}"/>
        ...
      </h:form>
      ...
    </f:view>
  </body>
</html>

 

 

 

 

 

正如你所看到,使用 EL 绑定在 JSF 页面上的 bidder item bid amount 字段都与 Bid entity 的属性是一致的。而“ bid ”和“ placeBid ”匹配的就是 @Named 所标注过的组件。当 WebBeans 第一次遇到符合 @Named 所标注的 Bid 实体时,它会在隐式的在后台创建一个 Bid 的实例,并将压入 request context ,供页面使用。同时你还要注意到 PlaceBidBean.addBid 方法也已经作为一个 action listener 绑定在 JSP 页面的添加按钮上。当按钮点击时,触发表单提交, WebBeans 所绑定的表单值又会自动依次中填充回 Bid 实体的各个属性,这一切还得归功于 @In annoation 。与 Bid entity 不同的是, EJB 这一块会从 JNDI look up PlaceBidBean ,然后将它放入 reqeust context 中。当添加按钮触发后, addBid 方法就会被调用, EJB 马上就会使用 JPA entity manager 来保存注入的实体。除了 request , application, session context, WebBeans 来发明了“ conversation context 。关于这些 contexts 的更多细节,请参看 WebBeans 的草案。

 

 

单凭以上代码就吹捧 WebBeans 编程模型的确没有多大的说服力。 WebBeans 用一种方法将 JSF,EJB JPA 整合起来,让人感觉这似乎是一个真正的 JavaEE 无缝开发平台。它的 out of box( 即拆即用 ) ,最小化 boilerplate code ,让你如同正在使用像 Ruby on Rails 这样的框架。你是不是这样看待的呢?你觉得还是这样很牵强?这样的模型有缺陷吗?

 

 

 

WebBeans 的依赖注入

 

 

绝大部分的企业应用程序组件无非就是: service 组件, DAOs 以及 domain model 组件。一般来说, JPA 是实现 domain model 组件的最佳选择;而 service DAO 组件又是 EJB 的不二选择。因为 EJBs 默认具备事务和线程安全的特性。 ( 很多人其实错误的认为 EJBs 默认也是支持 remote 的,这不是真的。 ) 如果你要使用声明式的 security remoting web services messaging scheduling 或者 asynchronous processing 的话, EJB 其实显然是一个更具优势的组件。上述这些 services 我们已经完全以 annoation 的形式给封装好成 EJB 组件了。

 

 

尽管如此,在一个应用程序里,总是还有一些组件并根本不需要声明式 servies ,不需要事务的感知 (transaction-aware) ,也不需要显式的线程安全保证。就拿 utilities helper 组件来说吧,它们确实没有必要。因为 EJB3.0 对那些非托管的组件,并不支持依赖注入,因此不把它们也搞成 EJB ,是没法直接使用依赖注入的。 WebBeans 的依赖注入很好的解决了这个问题——因为 @Component annoation 可以运用于任何 POJO 对象,不再局限于 EJBs JPA 实体了。刚才的咱们不就用 @In annoation Bid entity 注入到 PlaceBidBean 这个 stateless session bean 中去了吗?因此, WebBeans 同样可以将普通的组件注入到 EJBs 中去了

 

 

现在我们还是快速来看一个例子。假设用户输入的 bid amount 属性需要先通过一个 utility 类进行四舍五入到小数点两位,然后再保存,那么我们可以这么做:

 

@Component
public class MathUtil {
    ...
    public static double round(double value, int decimalPlaces) {
        BigDecimal converter = new BigDecimal(Double.toString(value));
        converter = converter.setScale(decimalPlaces, 
            BigDecimal.ROUND_HALF_UP);
        return converter.doubleValue();
    }
    ...
}

@Component
@Stateless
@Named("placeBid")
public class PlaceBidBean {
	@PersistenceContext
	private EntityManager entityManager;

      @In
      private Bid bid;

      @In
      private MathUtil mathUtil;

		public void addBid() {
          bid.setBidPrice(mathUtil.round(bid.getBidPrice(), 2));
	   	 	entityManager.persist(bid);
	}
}

 

 

在这个例子里,当 EJB 需要时,一个新的 MathUtil 的实例会被创建,然后注入到相应的 EJB bean 中去。尽管普通的 WebBeans 组件无法直接使用 EJB 的声明式 services ,但他们可以使用自己的依赖注入,生命周期回调( life-cycle callbacks ,使用 @PostConstruct/ @PreDestroy 实现)以及 interceptoer

 

@In @Component annotations 还只是冰山一角。 WebBeans JavaEE 带来了一套完整的依赖注入特性,包括 Guice 风格的方法创建和 annoation 绑定。注意所有的 EJB 类型包括消息驱动 Bean 都可以使用 WebBeans 特性。

 

 

 

WebBeans Interceptor Enhancements

 

 

相对于 EJB 来说, WebBeans 另一个主要的特性就是对现有 interceptor model( 拦截器模型 ) 的扩展。现在你可以直接在 EJBs 中使用 @Interceptor @Interceptors annotations 了。这样的结构既优雅又直接,不过不是非常灵活。 WebBeans 在些基础上,通过使用 annoation, ,引入了更加灵活的 Interceptor 机制,却没有仍然没有增加什么复杂度。理解它的最好方法还是代码。现在假设我们想使用一个 auditing interceptor 来拦截 EJB PlaceBidBean ,我们可以这么做:

 

 

 

@InterceptorBindingType
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface Audited {}

@Audited @Interceptor
public class AuditInterceptor {

    @AroundInvoke
    public Object audit(InvocationContext context) throws Exception {
        System.out.println("Entering: "
            + context.getMethod().getName());
        System.out.println("  with args: "
            + context.getParameters());
        return context.proceed();
    }
}

@Component
@Stateless
@Named("placeBid")
public class PlaceBidBean {
	@PersistenceContext
	private EntityManager entityManager;

      @In
      private Bid bid;

      @Audited
	public void addBid() {
	    entityManager.persist(bid);
	}
}
 

 

 

@Audited annotation 上面的那个 @InterceptorBindingType annotation 是用来声明它要绑定到一个 interceptor 上。与 EJB3.0 interceptor model 不同的是, WebBeans 通过使用 @Interceptor annotation 将一个 interceptor 绑定在一个或更多的 annotations 上。因此 @Audited @Interceptor annotations 同样放在 AuditInterceptor 上面表示凡是标注了 @Audited 的组件或方法都会被拦截器拦截。因此,当 placeBid 方法被调用时, AuditInterceptor 先会触发 audit 方法的执行。

 

 

除了它的间接性与灵活性外,我觉得这个扩展真的让代码变得更加可读。你觉得呢?是不是 EJB 规范也应该采纳这个扩展,正式成为 JavaEE 整体中的一部分呢?

 

 

 

继续工作

 

由于 JavaOne 大会的原因,专家组进度慢了下来也是情有可原。但不管怎么说,还是要言归正传,回到正常的工作中来。还有很多有趣的主题正在激烈的讨论着,它们是:

 

<!---->l         <!---->标准 JNDI 的映射机制同时由 JavaEE6 EJB3.1 两个专家组同时进行讨论。相信将来这一块应该没有多少水份。(笑:难道 JSR 专家组们自己觉得自己的东西都很有水份?)

<!---->l         <!---->支持 JavaSE 环境也可以使用 EJB3.1 (比如说单元测试)的工作仍然在进行着。实际上,继 OpenEJB EasyBeans Embedded JBoss 的路线之后, Embedded GlassFish 的动作也强烈的表明了它的决心。

<!---->l         <!---->一个很牛的扩展机制下在 JavaEE6 专家组中炸开了锅。而且好像它还是本次专家组的讨论最后一个 Big Thing 。如果通过审核,那么就会为 JavaEE 社区提供一个非标准的第三方基于 annoation 的声明式 services 组件。 BTW :究竟是什么,这么神秘, Raza 也真会“炒作”啊,呵呵)

 

你是怎么看待这些特性的?如果你觉得它们很重要,请大胆发表你的意见,并给专家组发 Email EJB3.1 专家组的电子邮件 jsr-318-comments@jcp.org WebBeans 专家组的电子邮件是 jsr-299-comments@jcp.org 。也可以随时给我 reza@rahmannet.net 发邮件。在此期间,我还会继续给你们介绍接下来专家组们正在讨论的特性,也许是本系列的最后一篇了。敬请期待。

 

 

 

参考

 

 

  1. New Features in EJB 3.1, http://www.theserverside.com/tt/articles/article.tss?l=NewFeaturesinEJB3-1 .
  2. New Features in EJB 3.1 - Part 2, http://www.theserverside.com/tt/articles/article.tss?l=NewFeaturesEJB31 .
  3. New Features in EJB 3.1 - Part 3, http://www.theserverside.com/tt/articles/article.tss?l=NewFeaturesEJB31-3 .
  4. JSR 316: Java EE 6, http://jcp.org/en/jsr/detail?id=316 .
  5. JSR 318: Enterprise JavaBeans 3.1, http://jcp.org/en/jsr/detail?id=318 .
  6. JSR 299: Web Beans, http://jcp.org/en/jsr/detail?id=299 .
  7. Seam, http://www.seamframework.org .
  8. Google Guice, http://code.google.com/p/google-guice/ .
16
0
分享到:
评论
8 楼 spiritfrog 2008-06-23  
引用

我很关系的是相应容器的热部署能力。
如果每次修改EJB都需要重新启动服务器的话,那它绝对不可能流行。

想当初用jboss+seam的时候,其他的基本都可以热部署。惟独ejb组件不行,最后没辙,直接把EJB用pojo换掉来做,但这样的话,容器换成tomcat又有何妨?seam对我来说唯一的好处就是不用在faces-config中添加managedbean了。

我很想使用EJB容器的事务等服务,但容器的热部署能力更本不能满足开发速度的要求

这种情况就会让人在技术选型的时候犹豫了,如果不是非ejb不可,多半会放弃掉。
7 楼 terranhao 2008-06-20  
我感觉EJB之所以流行不了关键是容器,至少我这就是这样的
6 楼 terranhao 2008-06-20  
这种变成模型真的很好很强大
我很关系的是相应容器的热部署能力。
如果每次修改EJB都需要重新启动服务器的话,那它绝对不可能流行。

想当初用jboss+seam的时候,其他的基本都可以热部署。惟独ejb组件不行,最后没辙,直接把EJB用pojo换掉来做,但这样的话,容器换成tomcat又有何妨?seam对我来说唯一的好处就是不用在faces-config中添加managedbean了。

我很想使用EJB容器的事务等服务,但容器的热部署能力更本不能满足开发速度的要求
5 楼 icess_ma 2008-06-20  
这个东西感觉和现在的seam差不多,只不过是把seam的东西变成了标准
4 楼 hantsy 2008-06-19  
Seam并不符合Web beans 标准。
3 楼 phoenixup 2008-06-19  
引用
目前有实现么, jboss seam?


Seam可以说是个预览或者风向标~
2 楼 rocwon 2008-06-19  
目前有实现么, jboss seam?
1 楼 zhoden 2008-06-19  
EJB3的发展真是不错,非常喜欢这个简洁的编程模型.以前看EJB2.0,也试验过;也用了ibatis,hibernate,感觉EJB3才是我真正值得深入的一个编程模型.毕竟他借鉴了开源的这些思想,然后总结再发展而来,所以技术也更超前,总的来说,很妙,很酷!我喜欢!

相关推荐

    EJB3.1深入浅出

    因此,在EJB 3.1中,Sun继续推进改革的步伐,针对EJB 2.1中的一些遗留问题进行了改进,并引入了一系列新的特性和技术。 #### 二、EJB 3.1 的主要特点 ##### 1. **No-Interface View (非接口视图)** EJB 3.1 引入...

    EJB3.1cookbook的源代码

    EJB 3.1是其一个重要的版本,相较于3.0,它引入了许多改进和新特性,使得EJB更加易用且更接近轻量级框架的开发体验。这个压缩包中的源代码是《EJB 3.1 Cookbook》一书的配套实例,可以帮助读者深入理解和应用书中...

    EJB3.1技术培训

    ### EJB3.1技术培训知识点详述 #### 一、EJB3.1概述 **EJB(Enterprise JavaBeans)3.1** 是Java EE平台中的一个重要组成部分,主要用于构建可伸缩、健壮的企业级应用程序。EJB3.1在前代版本的基础上做了大量的...

    EJB3.1_JSR 318-EJB3.1

    - **标题**:“EJB3.1_JSR 318-EJB3.1” - **描述**:此文档是EJB 3.1规范(JSR 318),与EJB 3.0相比,新增的功能包括: - 取消接口要求。 - 引入单例会话Bean(Singleton session bean)。 - 支持异步调用。 -...

    EJB3.1讲解

    ### EJB3.1讲解 #### EJB概要 ##### EJB基本概念 EJB(Enterprise JavaBeans)是由Sun Microsystems提出的、面向企业级应用的一种组件模型。它旨在为开发复杂的企业级应用程序提供一种标准化的方式。在EJB的概念...

    EJB 3.1 Cookbook

    《EJB 3.1 Cookbook》是一本针对企业级Java应用开发的专业书籍,主要涵盖了EJB(Enterprise JavaBeans)3.1版本的相关技术。EJB是Java EE(Java Platform, Enterprise Edition)的一部分,用于构建可扩展、安全且...

    EJB 3.1 Core

    EJB 3.1 Core Contracts主要包括了EJB容器与EJB组件之间的交互协议以及EJB组件必须遵循的一系列规则。这些合同定义了EJB组件的生命周期管理、远程调用接口、事务处理等核心功能,并且强调了EJB组件与容器之间约定的...

    _EJB3.1javaFX搭建工程.doc

    【EJB3.1简介】 EJB(Enterprise Java Beans)是Java平台上的一个核心标准,主要用于构建企业级分布式应用程序。EJB3.1是EJB规范的一个版本,它简化了之前版本的复杂性,提高了开发效率。EJB3.1引入了更多的注解驱动...

    EJB3.1与JBoss7.1.1在eclipse的实现

    标题《EJB3.1与JBoss7.1.1在eclipse的实现》意味着本文档将介绍如何使用EJB3.1标准在JBoss应用服务器7.1.1版本上进行企业级Java Bean(EJB)的开发,并通过Eclipse集成开发环境进行部署和测试。EJB3.1是一种用于简化...

    EJB.3.1.Cookbook.pdf

    ### EJB 3.1 Cookbook 知识点详解 #### 一、EJB 3.1 概述 **企业 Java Beans (EJB)** 是一种为服务器端应用提供组件架构的 Java 技术。EJB 3.1(Java EE 6 的一部分)是一个重要的里程碑,它在原有基础上进行了...

    javax.ejb-3.1.2.2.jar下载

    `javax.ejb`包是Java EJB规范的一部分,包含了一系列接口和类,这些是用来实现和管理EJBs的关键元素。 标题中的"javax.ejb-3.1.2.2.jar"是一个特定版本的EJB API的实现,它对应于EJB 3.1规范的2.2次小更新。这个jar...

    j2ee ejb3.1

    **J2EE EJB 3.1:企业级Java组件的增强与演进** Java 2 Platform, Enterprise Edition (J2EE) 是一个用于构建分布式、多层的企业级应用程序的平台,而Enterprise JavaBeans (EJB) 是J2EE的核心组成部分,它提供了一...

    EJB 3.1五大模式改进令Java EE 6更好用

    ### EJB 3.1五大模式改进令Java EE 6更好用 在深入解析EJB 3.1的五大改进模式之前,我们首先简要回顾一下EJB(Enterprise Java Beans)的基本概念及其在Java EE平台中的重要性。EJB是Java EE的核心组件之一,旨在...

    jboss7.1+ejb3.1建立第一个Ejb项目

    本篇文章将指导你如何使用JBoss7.1和EJB3.1在Eclipse3.7环境中创建你的第一个EJB项目。EJB(Enterprise JavaBeans)是一种Java平台上的组件模型,用于构建可扩展的、可靠的、安全的企业级应用。JBoss是Red Hat公司...

    javax.ejb-3.1.2.2_with-source.zip

    "javax.ejb-3.1.2.2_with-source.zip"是一个包含了javax.ejb-3.1.2.2版本的EJB组件,这个版本支持Java EE 6规范,且提供了源代码供开发者深入学习和调试。 EJB 3.1是EJB规范的一个重要里程碑,它极大地简化了EJB的...

    EJB3.1CookbookFreePdfBook.pdf 英文原版

    EJB 3.1 Cookbook – Free Pdf Book

    ejb3.1 cookbook

    标题《EJB3.1 Cookbook》表明这是一本关于企业Java Bean (EJB) 技术的实用指南,其第三版专注于提供一系列解决实际问题的简单而非常有效的方法。EJB是Java EE(现在称为Jakarta EE)的一部分,用于简化基于Java的...

    ejb-3_1-pr-api.zip_EJB a_ejb_ejb api

    EJB 3.1是该规范的一个重要版本,引入了许多改进以提高开发者的生产力和简化API。在这个ejb-3_1-pr-api.zip文件中,我们主要关注的是EJB 3.1的编程模型和API。 EJB 3.1的重要特性包括: 1. **注解驱动的开发**:与...

Global site tag (gtag.js) - Google Analytics