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

EJB调用的原理分析

阅读更多

    这篇文章分析深刻、清晰
<img src="/images/smiles/icon_biggrin.gif" alt="">

?

一个远程对象至少要包括4个class文件:远程对象;远程对象的接口;实现远程接口的对象的stub;对象的skeleton这4个class文件。
<br><br>
在EJB中则至少要包括10个class:
<br>
Bean类,特定App Server的Bean实现类
<br>
Bean的remote接口,特定App Server的remote接口实现类,特定App Server的remote接口的实现类的stub类和skeleton类
<br>
Bean的home接口,特定App Server的home接口实现类,特定App Server的home接口的实现类的stub类和skeleton类
<br><br>
和RMI不同的是,EJB中这10个class真正需要用户编写的只有3个,分别是Bean类和它的remote接口,home接口,至于其它的
7个class到底是怎么生成,被打包在什么地方,或者是否需要更多的类文件,会根据不同的App Server表现出比较大的差异,不能一概而论。
<br><br>
拿我最熟悉的Weblogic的来说吧,Weblogic的Bean实现类,以及两个接口的Weblogic的实现类是在ejbc的时候被打包到
EJB的jar包里面的,这3个class文件可以看到。而home接口和remote接口的Weblogic的实现类的stub类和skeleton类
是在EJB被部署到Weblogic的时候,由Weblogic动态生成stub类和Skeleton类的字节码,因此看不到这4个类文件。
<br><br>
对于一次客户端远程调用EJB,要经过两个远程对象的多次RMI循环。首先是通过JNDI查找Home接口,获得Home接口的实现类,这个过程
其实相当复杂,首先是找到Home接口的Weblogic实现类,然后创建一个Home接口的Weblogic实现类的stub类的对象实例,将它序列化
传送给客户端(注意stub类的实例是在第1次RMI循环中,由服务器动态发送给客户端的,因此不需要客户端保存Home接口的Weblogic实现类的
stub类),最后客户端获得该stub类的对象实例(普通的RMI需要在客户端保存stub类,而EJB不需要,因为服务器会把stub类的对象实例发
送给客户端)。
<br><br>
客户端拿到服务器给它的Home接口的Weblogic实现类的stub类对象实例以后,调用stub类的create方法,(在代码上就是
home.create(),但是后台要做很多事情),于是经过第2次RMI循环,在服务器端,Home接口的Weblogic实现类的skeleton
类收到stub类的调用信息后,由它再去调用Home接口的Weblogic实现类的create方法。
<br><br>
在服务端,Home接口的Weblogic实现类的create方法再去调用Bean类的Weblogic实现类的ejbCreate方法,在服
务端创建或者分配一个EJB实例,然后将这个EJB实例的远程接口的Weblogic实现类的stub类对象实例序列化发送给客户端。
<br><br>
客户端收到remote接口的Weblogic实现类的stub类的对象实例,对该对象实例的方法调用(在客户端代码中实际上就是对remote
接口的调用),将传送给服务器端remote接口的Weblogic实现类的skeleton类对象,而skeleton类对象再调用相应的remote
接口的Weblogic实现类,然后remote接口的Weblogic实现类再去调用Bean类的Weblogic实现类,如此就完成一次EJB对象的
远程调用。
<br><br>
看了一遍帖子,感觉还是没有说太清楚,既然写了帖子,就想彻底把它说清楚。
<br><br>
先拿普通RMI来说,有4个class,分别是远程对象,对象的接口,对象的stub类和skeleton类。而对象本身和对象的stub类同时都实现了接口类。而我们在客户端代码调用远程对象的时候,虽然在代码中操纵接口,实质上是在操纵stub类,例如:
<br>
接口类:Hello
<br>
远程对象:Hello_Server
<br>
stub类:Hello_Stub
<br>
skeleton类:Hello_Skeleton
<br><br>
客户端代码要这样写:
<br>
Hello h = new Hello_Stub();
<br>
h.getString();
<br><br>
我们不会这些写:
<br>
Hello_Stub h = new Hello_Stub();
<br>
h.getString();
<br><br>
因为使用接口适用性更广,就算更换了接口实现类,也不需要更改代码。因此客户端需要Hello.class和Hello_Stub.class这
两个文件。但是对于EJB来说,就不需要Hello_Stub.class,因为服务器会发送给它,但是Hello.class文件客户端是省不了的,必
须有。表面上我们的客户端代码在操纵Hello,但别忘记了Hello只是一个接口,抽象的,实质上是在操纵Hello_Stub。
<br><br>
拿Weblogic上的EJB举例子,10个class分别是:
<br>
Bean类:HelloBean (用户编写)
<br>
Bean类的Weblogic实现类:HelloBean_Impl (EJBC生成)
<br><br>
Home接口:HelloHome (用户编写)
<br>
Home接口的Weblogic实现类 HelloBean_HomeImpl(EJBC生成)
<br>
Home接口的Weblogic实现类的stub类 HelloBean_HomeImpl_WLStub(部署的时候动态生成字节码)
<br>
Home接口的Weblogic实现类的skeleton类 HelloBean_HomeImpl_WLSkeleton(部署的时候动态生成字节码)
<br><br>
Remote接口: Hello (用户编写)
<br>
Remote接口的Weblogic实现类 HelloBean_EOImpl(EJBC生成)
<br>
Remote接口的Weblogic实现类的stub类 HelloBean_EOImpl_WLStub(部署的时候动态生成字节码)
<br>
Remote接口的Weblogic实现类的skeleton类 HelloBean_EOImpl_WLSkeleton(部署的时候动态生成字节码)
<br><br>
客户端只需要Hello.class和HelloHome.class这两个文件。
<br><br>
HelloHome home = (Home) PortableRemoteObject.narrow(ctx.lookup("Hello"), HelloHome.class);
<br><br>
这一行代码是从JNDI获得Home接口,但是请记住!接口是抽象的,那么home这个对象到底是什么类的对象实例呢?很简单,用toString()输出看一下就明白了,下面一行是输出结果:
<br>
HelloBean_HomeImpl_WLStub@18c458
<br>
这表明home这个通过从服务器的JNDI树上查找获得的对象实际上是HelloBean_HomeImpl_WLStub类的一个实例。
<br>
接下来客户端代码:
<br><br>
Hello h = home.create()
<br><br>
同样Hello只是一个抽象的接口,那么h对象是什么东西呢?打印一下:
<br>
HelloBean_EOImpl_WLStub@8fa0d1
<br>
原来是HelloBean_EOImpl_WLStub的一个对象实例。
<br><br>
用这个例子来简述一遍EJB调用过程:
<br><br>
首先客户端JNDI查询,服务端JNDI树上Hello这个名字实际上绑定的对象是HelloBean_HomeImpl_WLStub,所以服务端将创建HelloBean_HomeImpl_WLStub的一个对象实例,序列化返回给客户端。
<br><br>
于是客户端得到home对象,表面上是得到HelloHome接口的实例,实际上是进行了一次远程调用得到了HelloBean_HomeImpl_WLStub类的对象实例,别忘记了HelloBean_HomeImpl_WLStub也实现了HelloHome接口。
<br><br>
然后home.create()实质上就是HelloBean_HomeImpl_WLStub.create(),该方法将发送信息给
HelloBean_HomeImpl_WLSkeleton,而HelloBean_HomeImpl_WLSkeleton接受到信息后,再去调用
HelloBean_HomeImpl的create方法,至此完成第1次完整的RMI循环。
<br><br>
注意在这次RMI循环过程中,远程对象是HelloBean_HomeImpl,远程对象的接口是HelloHome,对象的stub是
HelloBean_HomeImpl_WLStub,对象的skeleton是HelloBean_HomeImpl_WLSkeleton。
<br><br>
然后HelloBean_HomeImpl再去调用HelloBean_Impl的ejbCreate方法,而HelloBean_Impl的
ejbCreate方法将负责创建或者分配一个Bean实例,并且创建一个HelloBean_EOImpl_WLStub的对象实例。
<br><br>
这一步比较有趣的是,在前一步RMI循环中,远程对象HelloBean_HomeImpl在客户端有一个代理类
HelloBean_HomeImpl_WLStub,但在这一步,HelloBean_HomeImpl自己却充当了HelloBean_Impl的代
理类,只不过HelloBean_HomeImpl不在客户端,而是在服务端,因此不进行RMI。
<br><br>
然后HelloBean_EOImpl_WLStub的对象实例序列化返回给客户端,这一步也很有趣,上次RMI过程,主角是
HelloBean_HomeImpl和它的代理类HelloBean_HomeImpl_WLStub,但这这一次换成了
HelloBean_EOImpl和它的代理类HelloBean_EOImpl_WLStub来玩了。
<br><br><br>
Hello h = home.create();h.helloWorld();
<br><br>
假设Hello接口有一个helloWorld远程方法,那么表面上是在调用Hello接口的helloWorld方法,实际上是在调用HelloBean_EOImpl_WLStub的helloWorld方法。
<br><br>
然后HelloBean_EOImpl_WLStub的helloWorld方法将发送信息给服务器上的
HelloBean_EOImpl_WLSkeleton,而HelloBean_EOImpl_WLSkeleton收到信息以后,再去调用
HelloBean_EOImpl的helloWorld方法。至此,完成第2次完整的RMI循环过程。
<br><br>
在刚才HelloBean_EOImpl是作为远程对象被调用的,它的代理类是HelloBean_EOImpl_WLStub,但现在
HelloBean_EOImpl要作为HelloBean_Impl的代理类了。现在HelloBean_EOImpl去调用
HelloBean_Impl的helloWorld方法。注意!HelloBean_Impl继承了HelloBean,而HelloBean中的
helloWorld方法是我们亲自编写的代码,现在终于调用到了我们编写的代码了!
<br><br>
至此,一次EJB调用过程终于完成。在整个过程中,服务端主要要调用的类是HelloBean_Impl,
HelloBean_HomeImpl,HelloBean_HomeImpl_WLSkeleton,HelloBean_EOImpl,HelloBean_EOImpl_WLSkeleton。
客户端主要调用的类是HelloBean_HomeImpl_WLStub,HelloBean_EOImpl_WLStub,这两个类在客户端代码中并
不会直接出现,出现在代码中的类是他们的接口HelloHome和Hello,因此客户端需要这两个接口文件,而Stub是服务器传送给他们的。
     

 
0
1
分享到:
评论

相关推荐

    EJB调用原理分析

    NULL 博文链接:https://chenlinbo.iteye.com/blog/747723

    java源码包---java 源码 大量 实例

    摘要:Java源码,初学实例,EJB调用实例  各种EJB之间的调用源码示例,用远程接口的引用访问EJB、函数将被FirstEJB调用,同时它将调用secondEJB 基于JAVA的UDP服务器模型源代码 2个目标文件 摘要:Java源码,网络相关,...

    java源码包2

    摘要:Java源码,初学实例,EJB调用实例  各种EJB之间的调用源码示例,用远程接口的引用访问EJB、函数将被FirstEJB调用,同时它将调用secondEJB 基于JAVA的UDP服务器模型源代码 2个目标文件 摘要:Java源码,网络...

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

     SessionBean: Stateless Session Bean 的生命周期是由容器决定的,当客户机发出请求要建立一个Bean的实例时,EJB容器不一定要创建一个新的Bean的实例供客户机调用,而是随便找一个现有的实例提供给客户机。...

    java 面试题 总结

    SessionBean在J2EE应用程序中被用来完成一些服务器端的业务操作,例如访问数据库、调用其他EJB组件。EntityBean被用来代表应用系统中用到的数据。 对于客户机,SessionBean是一种非持久性对象,它实现某些在服务器上...

    java源码包3

    摘要:Java源码,初学实例,EJB调用实例  各种EJB之间的调用源码示例,用远程接口的引用访问EJB、函数将被FirstEJB调用,同时它将调用secondEJB 基于JAVA的UDP服务器模型源代码 2个目标文件 摘要:Java源码,网络...

    java源码包4

    摘要:Java源码,初学实例,EJB调用实例  各种EJB之间的调用源码示例,用远程接口的引用访问EJB、函数将被FirstEJB调用,同时它将调用secondEJB 基于JAVA的UDP服务器模型源代码 2个目标文件 摘要:Java源码,网络...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    浮动的广告 嵌套在html中 各种EJB之间的调用示例 7个目标文件 摘要:Java源码,初学实例,EJB调用实例 各种EJB之间的调用源码示例,用远程接口的引用访问EJB、函数将被FirstEJB调用,同时它将调用secondEJB 基于JAVA的...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    浮动的广告 嵌套在html中 各种EJB之间的调用示例 7个目标文件 摘要:Java源码,初学实例,EJB调用实例 各种EJB之间的调用源码示例,用远程接口的引用访问EJB、函数将被FirstEJB调用,同时它将调用secondEJB 基于JAVA的...

    J2EE应用开发详解

    364 19.5.1 管理员登录 364 19.5.2 模块管理 374 19.5.3 角色数据操作 383 19.5.4 资源操作 391 19.5.5 用户管理 394 19.6 小结 404 第20章 航空订票系统(JSF/Richfaces+EJB+JPA) 405 20.1 需求分析 405 20.2 基本...

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

    摘要:Java源码,初学实例,EJB调用实例  各种EJB之间的调用源码示例,用远程接口的引用访问EJB、函数将被FirstEJB调用,同时它将调用secondEJB 基于JAVA的UDP服务器模型源代码 2个目标文件 摘要:Java源码,网络相关,...

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

    摘要:Java源码,初学实例,EJB调用实例  各种EJB之间的调用源码示例,用远程接口的引用访问EJB、函数将被FirstEJB调用,同时它将调用secondEJB 基于JAVA的UDP服务器模型源代码 2个目标文件 摘要:Java源码,网络相关,...

    深入Java Servlet网络编程

    8 从Servlet中调用EJB 附录A 超文本传输协议 A. 1 MIME A. 2 URI和URL A. 3 HTTP详解 A. 3. 1 建立TCP/IP连接 A. 3. 2 客户端发送请求 A. 3. 3 服务器返回响应 A. 3. 4 HTTP报头 附录B Servlet API

    Struts原理、开发及项目实施

    Action通常称之为ActionBean,获取从ActionSevlet传来的FormBean,取出FormBean中的相关信息,并做出相关的处理,一般是调用Java Bean或EJB等。 流程:在Struts中,用户的请求一般以*.do作为请求服务名,所有的...

    健身房管理信息系统设计.doc

    组件在分布式服务器的组件容器中运行,如Servl et组件在Servlet容器上运行,EJB组件在EJB容器上运行,容器间通过相关的协议进行通讯 ,实现组件的相互调用。遵从这个规范的开发者将得到行业的广泛支持,使企业级应用的 ...

    二十三种设计模式【PDF版】

    主要用来对语言的分析,应用机会不多. 设计模式之 Visitor(访问者) 访问者在进行访问时,完成一系列实质性操作,而且还可以扩展. 设计模式引言 设计面向对象软件比较困难,而设计可复用的面向对象软件就更加困难。...

    【计算机软件毕业设计】二手车交易平台的分析、设计与实现文献综述1.doc

    关键词:SSH集成框架 Web 1主流Web开发框架分析 1.1 MVC结构模式和WebWork框架 2012年王欢认为MVC的工作原理是,使用MVC时,当用户向Web容器发送一个请求后, Web容器会根据请求和地址去调用一个Servlet进行处理,...

    JBPM4工作流应用开始指南.rar

    209 10.3 如何在活动中调用EJB方法 214 10.4 使用jms活动 215 10.4.1 模拟JMS服务 217 10.4.2 JMS文本消息 219 10.4.3 JMS Object消息 220 10.4.4 JMS Map消息 222 10.5 历史会话监听链 223 10.6 自定义Web任务表单 ...

    JAVA程序开发大全---上半部分

    14.4 创建直接调用Internet中的Web Service的客户端 252 14.4.1 创建客户端WeatherWSClient项目 253 14.4.2 使用WSDL生成客户端代码 253 14.4.3 创建Web Service客户端测试代码 255 14.5 本章小结 255 第15章 Java ...

Global site tag (gtag.js) - Google Analytics