`
yingfang05
  • 浏览: 124217 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

EJB3与EJB2架构对比

    博客分类:
  • ejb3
阅读更多
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名称了。 

JNDI Naming Context

  无论J2EE还是Java EE中,JNDI是一个好像不起眼,但是极其重要的概念,不理解JNDI可以说,对J2EE或JavaEE只了解一半。

  JNDI本来是EJB2中比较复杂的一个概念,不同容器有自己的JNDI名称,由此EJB2引入了第三者EJB-Reference,虽然解决了代码中耦合JNDI名称问题,但是又带来了更加烦琐的配置,这种现象当然被JavaEE5.0继续继承了下来,问题远非这么简单。

  J在Java EE5.0中(包括EJB3和Web环境),当我们需要访问一个JNDI环境下资源时,有两种方式:除了传统EJB2中的JNDI调用方式;还有一种就是:使用依赖注射Ioc模式,这个依赖注射的表达方式是使用annotations。

  因此,在EJB3中,必须好好搞清楚annotations、依赖注射和JNDI之间的关系,如果这个问题不弄明白,EJB3就绝非EJB2那么容易搞定,当然,搞定了的结果很简单,让人感觉简化轻量了,真不知道EJB3这种简化是不是有点象”掩耳盗铃“。

  可以总结一句:凡是EJB2中使用配置文件定义的;EJB3一般都可以使用 annotations定义(当然EJB3也支持配置文件定义);凡是EJB2通过JNDI寻找的资源(调用容器中其他EJB、调用环境变量等Resource资源等),都是可以依靠annotations+依赖注射机制完成。

JPA替代实体Bean

.   如果说EJB3与EJB2变化最大的部分,就是持久层使用Java Persistence API 替代了EJB2的实体Bean,这样,我们通过Evans DDD建模得到的Domain Model类可以直接持久化保存到数据库,不像EJB2中还需要在Model类和实体Bean中进行一次转换。

  EJB3引入EntityManager进行需要持久实体的查询及其新增修改;EntityManager非常类似JDBCTemp/HibernateTemplate等持久化模板。

  JPA和JDO以及Hibernate等O/R mapping框架都是非常相似的。

  虽然在JPA中,我们都可以使用Annotation来替代配置,实现很多过去需要专门配置文件才能实现功能,不再一定需要 每个服务器不同的cmp映射文件,增强了移植性,但是EJB3还是需要 一个叫persistence.xml配置文件,在这个配置中进行数据库JNDI配置;当然,还有一些和具体服务器有关的配置属性,如果使用JBoss,JBoss的JPA底层使用Hibernate实现,因此在persistence.xml要进行有关Hibernate属性配置:

<persistence>
  <persistence-unit name="Ejb3Tutorial">
    <jta-data-source>java:/TestDS</jta-data-source>
    <properties>
      <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
    </properties>
  </persistence-unit>
</persistence>

拦截器概念

  EJB3.0引入了类似AOP中的拦截器概念(注意,AOP不只等于拦截器,所以不能认为EJB3就是完全AOP了),JBoss使用JBossAOP来实现拦截器功能,自己定义的拦截器方法可以拦截任何一个业务方法或生命周期事件回调;拦截方法可以在bean中定义或专门的拦截器类。

@Stateless
@Interceptors( { NullChecker.class, ArgumentsChecker.class })
public class StatelessSessionBean implements StatelessSession {

  // This business method is called after
  // the above two interceptor's @AroundInvoke
  // methods are invoked. Hence it is guaranteed
  // that the argument to this method is not null
  // and it starts with a letter
  public String initUpperCase(String val) {
    String first = val.substring(0, 1);
    return first.toUpperCase() + val.substring(1);
  }

}


  NullChecker和ArgumentsChecker是StatelessSessionBean两个拦截器,在拦截器NullChecker中,必须指定的拦截方法为@AroundInvoke。

public class NullChecker {

  @AroundInvoke
  public Object checkIfNull(InvocationContext ctx)
        throws Exception {
      Method method = ctx.getMethod();
      if (method.getName().equals("initUpperCase")) {
        String param = (String) (ctx.getParameters()[0]);
      }
       .........

      }
       // Proceed to the next interceptor
      return ctx.proceed();
  }

}


总结

  总之,从上面EJB2和EJB3的总结上看,EJB3.0在EJB2基础上,引入了更多概念,最大变化就是Annotation替代了配置文件,对于一些配置文件厌恶者来说,是一个好事;但是在实战中,在一些依赖注射不能照顾到地方,我们还必须和更加复杂的JNDI名称打交道,这恐怕是EJB3的一个不是很完美的地方。

  关于EJB3中可测试性的优点被很多人津津乐道,将EJB脱离容器测试,虽然可以进行微观的单元测试,但是脱离容器就是脱离特定完整的业务场景,所以,基于容器的(也就是基于完整的业务场景)单点跟踪调试才是最重要的,这些必须依赖开发工具的发展,目前已经在Eclipse3.2以后版本+WPT(或JBossIDE/Lomboz)中实现,这个功能适合大部分J2EE/JavaEE程序。
分享到:
评论

相关推荐

    EJB 3 的理想与现实

    文章由陈俊亨撰写,通过回顾EJB的发展历程,对比了EJB 1.0、2.0与3.0的不同,特别是对EJB 3的优势进行了详尽阐述。 ### 认识 EJB 3 EJB 3作为Java企业级应用框架的重要组成部分,标志着企业级Java开发的一次重大...

    ejb2.rar_bmp ejb2_ejb2_ejb2 cmp b

    在EJB架构中,通常会有一个Web应用(WAR文件)作为客户端,调用EJB服务(EAR文件)中的业务逻辑。 5. **CMP与BMP的区别**:CMP简化了开发过程,但可能限制了数据库访问的灵活性;而BMP提供了更大的自由度,允许...

    EJB&Spring;详细对比

    ### EJB与Spring详细对比分析 #### 一、引言 在现代企业级应用开发领域,EJB(Enterprise JavaBeans)与Spring框架均扮演着重要角色。随着技术的发展与需求的变化,两者之间的对比成为了业界广泛关注的话题。本文...

    EJB教程(技术规范)

    五、EJB与现代框架的对比 虽然EJB在过去是企业级Java开发的首选,但随着Spring、Quarkus等轻量级框架的崛起,EJB的应用逐渐减少。这些框架提供了更灵活的编程模型,降低了复杂性,同时也保留了EJB的部分核心特性,如...

    EJB2.0 Entity bean(PDF) .zip_EJB2 enti_EJB2.0 P_ejb_ejb2 CMP sup

    EJB 2.0与后续版本的对比 EJB 3.0引入了注解,大大减少了XML配置,使得开发更加简洁。同时,CMP的映射机制得到了改进,更加接近ORM(对象关系映射)框架,如Hibernate。 ### 学习资源 提供的"www.pudn.com.txt"...

    EJB开发总结

    EJB 与微服务对比 虽然EJB在传统企业应用中广泛应用,但随着微服务架构的兴起,轻量级框架如Spring Boot变得更为流行。微服务强调单一职责、独立部署,而EJB更适合大型、复杂的集成系统。 ### 9. 性能优化 EJB的...

    ejb全示例教程

    - EJB 3.x的新特性:对比早期版本,讨论EJB 3.x引入的简化开发和提高生产力的改进。 本教程适合对Java EE有一定了解,希望深入学习EJB技术的开发者。通过学习,你可以掌握如何在企业级应用中使用EJB来构建高效、...

    传智播客ejb3.0教学ppt

    #### 四、EJB 3.0与Spring框架的对比 - **竞争与互补**:尽管Spring框架和Hibernate提供了类似的事务管理和持久化服务,但EJB 3.0更适合于需要分布式能力的应用场景。Spring框架侧重于提供轻量级的解决方案,而EJB ...

    java面试精品全集[ejb 部分]

    **EJB特性对比** - **Persistent MDB**:持久化消息驱动Bean(MDB)确保消息传递的可靠性,即使EJB容器故障,消息也会在MDB可用时重新发送。 - **Non-Persistent MDB**:非持久化MDB不保证消息传递的可靠性,一旦EJB...

    ejb应用开发详解…………

    六、EJB 3.x与EJB 2.x的对比 EJB 3.x版本引入了显著的改进,降低了EJB的学习曲线和使用难度。它引入了注解(Annotations)来简化配置,使得EJB更易读、易写。此外,EJB 3.x取消了对EJB 2.x中的Home Interface和...

    EJB3.0培训教材

    【EJB3.0与Spring的对比】 虽然Spring和Hibernate等框架提供了与EJB类似的服务,例如事务管理和持久化,但在分布式场景下,EJB具有天然优势。Spring更适合轻量级应用,而EJB则针对大型企业级分布式应用。EJB3.0在...

    POJO Application Frameworks_ Spring Vs. EJB 3

    该标题与描述指出了一篇关于POJO(Plain Old Java Object)应用框架的文章,主要对比了Spring框架与EJB 3.0(Enterprise JavaBeans 3.0)。文章旨在深入探讨这两种框架在企业级Java应用程序开发中的应用,以及它们...

    EJB 3.0 简介

    EJB允许开发者将业务逻辑与展示层、数据访问层进行解耦,从而实现更灵活、可扩展的系统架构。 **EJB采用Java编程语言的原因** Java是EJB开发的首选语言,因为它提供了多种优势: 1. **接口与实现分离**:Java支持...

    SSH框架和JPA+EJB+JSF框架的比较

    #### 五、EJB与Spring对比 - **EJB**:虽然EJB提供了强大的企业级服务支持,如事务管理、消息驱动组件等,但由于其复杂的API和配置要求,使得学习和维护成本较高。 - **Spring**:相比之下,Spring框架以其轻量级...

    EJB资料文档

    3. **EJB3.0与之前的版本对比** - **轻量级**:EJB3.0减少了对XML配置的依赖,更多地使用注解(Annotation)来描述组件属性,降低了学习和使用的难度。 - **POJO(Plain Old Java Object)**:实体bean不再强制...

    EJB必须掌握的概念

    在J2EE架构中,Web端被视为“客户端”,与EJB交互以实现更高级别的功能。 ### 3. EJB的分类及其功能 EJB分为三类:会话Bean(Session Bean)、实体Bean(Entity Bean)、消息驱动Bean(Message-Driven Bean)。 -...

    ejb2.0 api文档快速开发

    5. EJB与现代框架的对比: - 现代框架如Spring和Java EE 7以后的版本(现在的Jakarta EE)借鉴了EJB的很多思想,但更加轻量级,易于理解和使用。 - EJB 2.0的很多功能在现代框架中被简化或替换,例如,Spring的AOP...

    传智播客-黎活明-EJB3.0.pptx

    ### EJB3.0与Spring的对比 EJB3.0和Spring框架虽然都提供了事务管理和持久化服务,但它们的侧重点不同。Spring最初被设计为一种轻量级的框架,适用于非分布式或小型项目。相比之下,EJB3.0自诞生起就面向大型分布式...

Global site tag (gtag.js) - Google Analytics