WEB开发网
开发学院WEB开发Jsp 实战角度比较EJB2和EJB3的异同 阅读

实战角度比较EJB2和EJB3的异同

 2008-01-05 08:25:11 来源:WEB开发网   
核心提示:本文从实战角度比较EJB2和EJB3的异同,通过深入剖析揭示EJB3.0的真相,实战角度比较EJB2和EJB3的异同,EJB3.0真是带来简化?还是一种表象上的简化?EJB3.0真的变得轻量了,还是披着羊皮的狼?EJB编程模型的简化首先,这时,你就必须使用到那个变化不定的缺省JNDI名称了,EJB3简化的一个主要表现是
  本文从实战角度比较EJB2和EJB3的异同,通过深入剖析揭示EJB3.0的真相,EJB3.0真是带来简化?还是一种表象上的简化?EJB3.0真的变得轻量了,还是披着羊皮的狼?

EJB编程模型的简化

首先,EJB3简化的一个主要表现是:在EJB3中,一个EJB不再象EJB2中需要两个接口一个Bean实现类,虽然我们以前使用JBuilder这样可视化开发工具自动生成了EJB2的这三个类,似乎不觉得复杂,但是当EJB个数增加时,就显得累赘了。

简化后的EJB3的sessionBean依靠annotations元注释来定义SessionBean的类型,也就是说,EJB2中的SessionBean类型区分在EJB3继续继续,只不过书写代码的方式不同而已,例如下代码使用@Stateless表示一个无状态Bean.

 package example;

@Stateless
public class TestSessionBean implements TestSessionLocal{
public void xxxx(){

  System.out.PRintln("hello");  

}

}

上述Session Bean中没有了EJB2中ejbCreate等多余方法,这样TestSessionBean很象一个普通javaBeans了。是不是简单?先别急,我们需要接着看看这个TestSessionBean是如何调用?

在EJB2中,一个EJB对象的调用需要经过两个步骤:JNDI寻找和工厂创建,如下例:

 Context ctx = new InitialContext();
TestSessionLocalHome home = (TestSessionLocalHome)ctx.lookup("java:comp/env/ejb/TestSession");
TestSessionLocal bean = home.create();

bean.xxxx();//真正目的 对象使用

其实上述代码最后一句才是我们真正目的,但是为了这个目的,必须经过前面冗长的代码创建,而在EJB3中,为创建型模式的Ioc模式(或称依靠注射)取代了home.create这样简单工厂创建模式,以一种更加松耦合和简洁的方式解决了对象创建问题,可以让我们精力更集中在对象的使用上了。

进入讨论组讨论。  

  下面是annotations+Ioc/DI的EJB3调用代码:

 @EJB //注重这里后面是空白
private TestSessionLocal testbean; //使用接口声明

public void invoke(){
  testbean.xxxx(); //直接使用

}

上述EJB3调用代码中,@EJB后面是空白,这其实使用了TestSessionLocal的缺省JNDI名称,一直到这里,我们一直满足于EJB3的简化,但是假如研究@EJB语法后,会发现其完整写法如下:

 @EJB(
name = “ejb/shopping-cart”,//被调用者Cart实现类的ejb-reference名称
beanName = “cart1”, //被调用者的名称 beanName
beanInterface = ShoppingCart.class, //接口名称
description = “The shopping cart for this application”
)
private Cart myCart;

上述完整@EJB写法适用于同一个接口有多个实现子类时,其中要害是 beanName的定义:beanName是被调用EJB的类名 (不带包名,称为unqualified name ),或者, 假如被调用EJB有 xml descriptor定义, 它就是配置项ejb-name值(假如你使用过EJB2,就轻易理解这个ejb-name了)。

@EJB还有一个属性mappedName,这是被调用者的JNDI名称,一般不使用,因为这个JNDI名称和具体服务器有关,假如是JBoss4,那么它的缺省形式是:"EAR-FILE-BASE-NAME/BEAN——CLASS-NAME/local" (or remote)。 也就是:被调用者EJB所在EAR包的名称/Bean实现子类(不带包名)/local,假如是remote调用,就是remote. 假如这个EJB被打包在jar包中,那么JNDI名称就是EJB-CLASS-NAME/local and EJB-CLASS-NAME/remote,当然,作为替换@RemoteBinding 和 @LocalBinding 也可定义JNDI名称。

也就是说:JBoss的EJB3中,假如你不使用XML配置,直接使用annotations,那么JNDI缺省名称没有一个统一规定名称,有的可以直接是类名;在JBoss中还和EJB打包的形式有关,是动态变化的。假如你以为在EJB3中不会接触到这个变化的JNDI缺省名称,那你就错了。

JBoss 4 在Servlet中不支持类似EJB调用EJB那样的依靠注射 binding-by-injection,因为Web容器和EJB容器是两个不同容器,当然借助另外JBoss Seam则是另外一回事,因此,在Web层调用EJB,就必须通过JNDI绑定一个session bean,这时,你就必须使用到那个变化不定的缺省JNDI名称了。

进入讨论组讨论。


Tags:实战 角度 比较

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接