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

EJB2和EJB3在架构上的不同点

阅读更多
EJB编程模型的简化
首先,EJB3简化的一个主要表现是:在EJB3中,一个EJB不再象EJB2中需要两个接口一个Bean实现类,虽然我们以前使用JBuilder这样可视化开发工具自动生成了EJB2的这三个类,好像不觉得复杂,但是当EJB个数增加时,就显得累赘了。
简化后的EJB3的sessionBean依靠annotations元注释来定义SessionBean的类型,也就是说,EJB2中的SessionBean类型区分在EJB3继续继承,只不过书写代码的方式不同而已,例如下代码使用@Stateless表示一个无状态Bean。
package example;@Statelesspublic 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();//真正目的 对象使用
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 letterpublic String initUpperCase(String val) {String first = val.substring(0, 1);return first.toUpperCase() + val.substring(1);}}
NullChecker和ArgumentsChecker是StatelessSessionBean两个拦截器,在拦截器NullChecker中,必须指定的拦截方法为@AroundInvoke。
public class NullChecker {@AroundInvokepublic 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 interceptorreturn ctx.proceed();}}
总结
总之,从上面EJB2和EJB3的总结上看,EJB3.0在EJB2基础上,引入了更多概念,最大变化就是Annotation替代了配置文件,对于一些配置文件厌恶者来说,是一个好事;但是在实战中,在一些依赖注射不能照顾到地方,我们还必须和更加复杂的JNDI名称打交道,这恐怕是EJB3的一个不是很完美的地方。
关于EJB3中可测试性的优点被很多人津津乐道,将EJB脱离容器测试,虽然可以进行微观的单元测试,但是脱离容器就是脱离特定完整的业务场景,所以,基于容器的(也就是基于完整的业务场景)单点跟踪调试才是最重要的,这些必须依赖开发工具的发展,目前已经在Eclipse3.2以后版本+WPT(或JBossIDE/Lomboz)中实现,这个功能适合大部分J2EE/JavaEE程序。
所以,个人对脱离容器的测试要求并不以为然,而这个曾经是Martin Fowler定义POJO的主要内容,因为在过去容器概念刚刚出现时,很多人都有容器恐惧症,以为容器都是不透明的,我们的业务对象放入进去,就失去了控制,这些都是落后设计观念导致,其实,Java语言本身提供的可跟踪性和介入性是非常强大,目前性能跟踪工具Profiler可以在容器运行时,跟踪到容器中某个具体类占据CPU多少,占用多少内存资源,那么一个单点调试岂是一个个所谓容器可以阻挡的?容器是Java语言的特点,ClassLoader决定了Java就是一个容器性的语言,关键这个容器是必须透明的。
其实上述代码最后一句才是我们真正目的,但是为了这个目的,必须经过前面冗长的代码创建,而在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”, //被调用者的名称 beanNamebeanInterface = 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+依赖注射机制完成。
分享到:
评论

相关推荐

    EJB2和EJB3的架构异同.doc

    EJB2.0和EJB3.0是两个重要的版本,它们在架构上有显著的不同,主要体现在编程模型的简化、实体Bean的替换以及拦截器的引入。 在EJB2.0中,一个EJB通常包含三个类:一个接口(Home Interface)、一个远程接口...

    实战EJB 实战EJB 实战EJB

    通过将业务逻辑与基础架构关注点(如事务管理、安全性、持久性和并发控制)分离,EJB允许开发者专注于核心业务逻辑的实现,而将非功能性的复杂性交由容器来处理。 **EJB体系结构** EJB体系结构主要包括三个主要...

    EJB 3实战 带书签

    虽然EJB 3是Java EE标准的一部分,但开发者需要了解如何确保应用可以在不同的Java EE容器和应用服务器上运行。这涉及到容器相关的配置、兼容性和最佳实践的讨论。互操作性部分则关注于EJB与不同技术(如Web Services...

    EJB 编程及 J2EE 系统架构和设计

    综上所述,EJB编程及J2EE系统架构和设计涉及了企业级应用开发的多个方面,从组件技术到数据访问,再到分布式通信和安全性,构成了一个完整而强大的企业级应用开发框架。通过掌握这些技术,开发者可以构建出高性能、...

    EJB编程和J2ee系统架构和设计

    综上所述,EJB编程和J2EE系统架构涉及众多技术和设计原则,它们共同构建了强大的企业级应用开发框架,能够处理复杂的业务需求并提供可靠的分布式服务。通过深入理解和熟练运用这些概念,开发者可以构建出高效、可...

    EJB3规范 简体中文

    EJB3 引入了许多注释符来定义和配置不同的 EJB 组件,这些注释符可以显著减少 XML 配置的需求,并使代码更加简洁易读。 ##### 3.1 特定类型 Bean 的注释符 这些注释符用于标识不同类型的 EJB 组件,如无状态会话 ...

    一个宠物商店,基EJB3分布技术开发

    综上所述,这个项目展示了如何使用EJB3技术构建一个分布式宠物商店应用,通过Swing和Struts2提供不同的用户界面,是学习Java企业级开发和分布式系统的好案例。对于开发者来说,这将涉及Java编程、EJB3规范、数据库...

    在PowerBuilder中呼叫EJB元件-以mail EJB為例

    标题和描述中提及的知识点主要集中在如何在PowerBuilder环境中调用EJB(Enterprise Java Beans)组件,特别地,以一个邮件服务EJB作为实例进行说明。以下是根据标题、描述、标签以及部分内容详细展开的知识点: ###...

    ejb 学习笔记6

    当两个EJB(例如EJB A和EJB B)位于同一个应用服务器上时,可以直接使用默认的JNDI上下文进行查找,而无需提供额外的JNDI入口信息。这种方式相对简单,但在JNDI名字发生改变时,代码需要调整。具体实现步骤如下: `...

    EJB-api.rar

    Enterprise JavaBeans(EJB)是Java平台上用于构建可部署在企业级服务器上的分布式应用程序的框架。EJB-api.rar 是一个包含EJB规范API的压缩包,它为开发人员提供了访问和使用EJB技术的接口和类。以下是关于EJB的...

    WTC暴露ejb服务说明

    2. 设置Local Tuxedo Access Points:定义本地Tuxedo访问点,提供本机的网络地址和一个未被占用的端口号,使得Weblogic能够监听来自Tuxedo的请求。 3. 定义Remote Tuxedo Access Points:配置远程Tuxedo服务器的...

    实战EJB.pdf

    - **多平台支持**:EJB组件可以在多种平台上运行,提高了应用的灵活性和兼容性。 - **商务重点**:主要关注于商务逻辑的处理,简化了复杂应用的开发过程。 #### 二、EJB体系结构 EJB体系结构包括三个主要部分:...

    EJB简介Enterprise Java Bean 下载

    3. 可移植性:EJB是标准化的组件,可以在不同的应用服务器之间轻松迁移。 【EJB与JNDI】 Java Naming and Directory Interface(JNDI)是Java平台的标准服务,用于查找和管理分布式环境中的资源。在J2EE环境中,EJB...

    EJB的入门教材.pdf

    2. EJB的架构和组件类型:EJB架构主要由三种类型的组件构成,分别是Stateless Session Beans(无状态会话bean)、Stateful Session Beans(有状态会话bean)和Message-Driven Beans(消息驱动bean)。这些组件在企业...

    ejb.rar_Java EJB_ejb

    Enterprise Java Beans(EJB)是Java平台上用于构建可部署在企业级服务器上的分布式应用程序的核心技术。EJB标准由Java Community Process(JCP)制定,它为开发者提供了在服务器端进行业务逻辑处理的能力,并且提供...

    学习EJB1

    在"学习EJB1"这个主题中,我们主要会探讨以下几个核心知识点: 1. **EJB组件类型**:EJB1主要包含两种组件,分别是Session Beans(会话bean)和Entity Beans(实体bean)。Session Beans代表了客户端与服务器之间的...

Global site tag (gtag.js) - Google Analytics