`
sakakokiya
  • 浏览: 487320 次
  • 性别: 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+依赖注射机制完成。
分享到:
评论

相关推荐

    Hibernate实战(第2版 中文高清版)

     1.4.4 Hibernate、EJB 3和JPA简介   1.5 小结   第2章 启动项目   2.1 启动Hibernate项目   2.1.1 选择开发过程   2.1.2 建立项目   2.1.3 Hibernate配置和启动   2.1.4 运行和测试应用程序   2.2...

    常用J2EE应用服务器简介.docx

    (三)不同点: 功能性: WebLogic更加强大。weblogic是j2ee的应用服务器(application server),包括ejb ,jsp,servlet,jms等等,全能型的。是商业软件里排名第一的容器(JSP、servlet、EJB等),并提供其他如JAVA编辑等...

    java基础题 很全面

    6. JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么? 17 7. forward 和redirect的区别 17 8. 说出在JSP页面里是怎么分页的? 17 9. 什么情况下调用doGet()和doPost()? 17 10. servlet的生命周期 17 11. ...

    java面试宝典

    160、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么? 38 161、AJAX的全称是什么? 介绍一下AJAX 38 162、Ajax主要包含了哪些技术? 38 163、主要的Ajax框架都有什么? 38 164、介绍一下XMLHttpRequest...

    Java体系架构知识点整理,包括Java基础、Spring、MySQL、算法题等.zip

    到处运行(Write Once, Run Anywhere)”,这意味着开发者可以使用Java编写应用程序,并在支持Java的任何平台上无需重新编译即可运行,这得益于其独特的跨平台性,通过Java虚拟机(JVM)实现不同操作系统上的兼容。...

    超级有影响力霸气的Java面试题大全文档

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    千方百计笔试题大全

    160、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么? 38 161、AJAX的全称是什么? 介绍一下AJAX 38 162、Ajax主要包含了哪些技术? 38 163、主要的Ajax框架都有什么? 38 164、介绍一下XMLHttpRequest...

    java 面试题 总结

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    Java面试宝典2010版

    17、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么? 18、MVC的各个部分都有那些技术来实现?如何实现? 19、我们在web应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,如何输出一个某种编码的...

    Spring攻略(第二版 中文高清版).part2

    6.2 在你的Servlet和过滤器中使用Spring 214 6.2.1 问题 214 6.2.2 解决方案 215 6.2.3 工作原理 215 6.3 将Spring与Struts 1.x集成 220 6.3.1 问题 220 6.3.2 解决方案 220 6.3.3 工作原理 220 6.4...

    JAVA上百实例源码以及开源项目

    (1)提高文件的共享性(计算机程序和/或数据),(2)鼓励间接地(通过程序)使用远程计算机,(3)保护用户因主机之间的文件存储系统导致的变化,(4)为了可靠和高效地传输,虽然用户可以在终端上直接地使用它,...

    Java消息服务(第2版)

    你将学习到JMS如何帮助你解决许多架构难题,如整合不同的系统和应用程序,增加可扩展性,消除系统瓶颈,支持并行处理,提升灵活性和敏捷性。由于更新了JMS 1.1,第二版还说明了厂商无关的规范将有助于你写基于...

    最新Java面试宝典pdf版

    17、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么? 90 18、MVC的各个部分都有那些技术来实现?如何实现? 90 19、我们在web应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,如何输出一个某种...

    Java面试笔试资料大全

    17、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么? 90 18、MVC的各个部分都有那些技术来实现?如何实现? 90 19、我们在web应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,如何输出一个某种...

    JAVA上百实例源码以及开源项目源代码

    (1)提高文件的共享性(计算机程序和/或数据),(2)鼓励间接地(通过程序)使用远程计算机,(3)保护用户因主机之间的文件存储系统导致的变化,(4)为了可靠和高效地传输,虽然用户可以在终端上直接地使用它,...

    JAVA面试宝典2010

    17、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么? 90 18、MVC的各个部分都有那些技术来实现?如何实现? 90 19、我们在web应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,如何输出一个某种...

    Java面试宝典-经典

    17、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么? 90 18、MVC的各个部分都有那些技术来实现?如何实现? 90 19、我们在web应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,如何输出一个某种...

    java面试题大全(2012版)

    17、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么? 90 18、MVC的各个部分都有那些技术来实现?如何实现? 90 19、我们在web应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,如何输出一个某种...

Global site tag (gtag.js) - Google Analytics