首页 > 学院 > 开发设计 > 正文

深入掌握Java技术 EJB调用原理分析二

2019-11-18 12:33:11
字体:
来源:转载
供稿:网友

  Home接口的Weblogic实现类的stub类 ((Hello Bean))_HomeImpl_WLStub(部署的时候动态生成字节码)
  
  Home接口的Weblogic实现类的skeleton类 ((Hello Bean))_HomeImpl_WLSkeleton(部署的时候动态生成字节码)
  
  Remote接口:Hello (用户编写)
  
  Remote接口的Weblogic实现类 ((Hello Bean))_EOImpl(EJBC生成)
  
  Remote接口的Weblogic实现类的stub类 ((Hello Bean))_EOImpl_WLStub(部署的时候动态生成字节码)
  
  Remote接口的Weblogic实现类的skeleton类 ((Hello Bean))_EOImpl_WLSkeleton(部署的时候动态生成字节码)
  
  客户端只需要Hello.class和HelloHome.class这两个文件。
  
  ((Hello Home)) home = (Home)
  ((Portable Remote Object)).narrow(ctx.lookup("Hello"),
  ((Hello Home)).class);
  
  这一行代码是从JNDI获得Home接口,但是请记住!接口是抽象的,那么home这个对象到底是什么类的对象实例呢?很简单,用toString()输出看一下就明白了,下面一行是输出结果:
  
  ((Hello Bean))_HomeImpl_WLStub@18c458
  
  这表明home这个通过从服务器的JNDI树上查找获得的对象实际上是HelloBean_HomeImpl_WLStub类的一个实例。
  
  接下来客户端代码:
  
  Hello h = home.create()
  
  同样Hello只是一个抽象的接口,那么h对象是什么东西呢?打印一下:
  
  ((Hello Bean))_EOImpl_WLStub@8fa0d1
  
  原来是HelloBean_EOImpl_WLStub的一个对象实例。
  
  用这个例子来简述一遍EJB调用过程:
  
  首先客户端JNDI查询,服务端JNDI树上Hello这个名字实际上绑定的对象是HelloBean_HomeImpl_WLStub,所以服务端将创建HelloBean_HomeImpl_WLStub的一个对象实例,序列化返回给客户端。
  
  于是客户端得到home对象,表面上是得到HelloHome接口的实例,实际上是进行了一次远程调用得到了HelloBean_HomeImpl_WLStub类的对象实例,别忘记了HelloBean_HomeImpl_WLStub也实现了HelloHome接口。
  
  然后home.create()实质上就是HelloBean_HomeImpl_WLStub.create(),该方法将发送信息给HelloBean_HomeImpl_WLSkeleton,而HelloBean_HomeImpl_WLSkeleton接受到信息后,再去调用HelloBean_HomeImpl的create方法,至此完成第1次完整的RMI循环。
  
  注重在这次RMI循环过程中,远程对象是HelloBean_HomeImpl,远程对象的接口是HelloHome,对象的stub是HelloBean_HomeImpl_WLStub,对象的skeleton是HelloBean_HomeImpl_WLSkeleton。
  
  然后HelloBean_HomeImpl再去调用HelloBean_Impl的ejbCreate方法,而HelloBean_Impl的ejbCreate方法将负责创建或者分配一个Bean实例,并且创建一个HelloBean_EOImpl_WLStub的对象实例。
  
  这一步比较有趣的是,在前一步RMI循环中,远程对象HelloBean_HomeImpl在客户端有一个代理类HelloBean_HomeImpl_WLStub,但在这一步,HelloBean_HomeImpl自己却充当了HelloBean_Impl的代理类,只不过HelloBean_HomeImpl不在客户端,而是在服务端,因此不进行RMI。
  
  然后HelloBean_EOImpl_WLStub的对象实例序列化返回给客户端,这一步也很有趣,上次RMI过程,主角是HelloBean_HomeImpl和它的代理类HelloBean_HomeImpl_WLStub,但这这一次换成了HelloBean_EOImpl和它的代理类HelloBean_EOImpl_WLStub来玩了。
  
  Hello h = home.create();h.helloWorld();
  
  假设Hello接口有一个helloWorld远程方法,那么表面上是在调用Hello接口的helloWorld方法,实际上是在调用HelloBean_EOImpl_WLStub的helloWorld方法。
  
  然后HelloBean_EOImpl_WLStub的helloWorld方法将发送信息给服务器上的HelloBean_EOImpl_WLSkeleton,而HelloBean_EOImpl_WLSkeleton收到信息以后,再去调用HelloBean_EOImpl的helloWorld方法。至此,完成第2次完整的RMI循环过程。
  
  在刚才HelloBean_EOImpl是作为远程对象被调用的,它的代理类是HelloBean_EOImpl_WLStub,但现在HelloBean_EOImpl要作为HelloBean_Impl的代理类了。现在HelloBean_EOImpl去调用HelloBean_Impl的helloWorld方法。注重!HelloBean_Impl继续了HelloBean,而HelloBean中的helloWorld方法是我们亲自编写的代码,现在终于调用到了我们编写的代码了!
  
  至此,一次EJB调用过程终于完成。在整个过程中,服务端主要要调用的类是HelloBean_Impl, Hello Bean?_HomeImpl,HelloBean_HomeImpl_WLSkeleton,HelloBean_EOImpl,HelloBean_EOImpl_WLSkeleton。
  
  客户端主要调用的类是HelloBean_HomeImpl_WLStub,HelloBean_EOImpl_WLStub,这两个类在客户端代码中并不会直接出现,出现在代码中的类是他们的接口HelloHome和Hello,因此客户端需要这两个接口文件,而Stub是服务器传送给他们的。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表