手机站
网通分站
电信主站
密 码:
用户名:
热门关键字:  虚拟主机  cn域名  asd  ddd  域名注册
当前位置 : 主页>程序设计>Java技术>列表

EJB工作原理学习笔记!

来源:互联网 作者:west263.com 时间:2008-02-23 点击:
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

_EJS_result = EJSStatelessUserServiceHomeBean_a940aa04.create();
}


5. #4又调用EJSStatelessUserServiceHomeBean_a940aa04.create()
代码:

UserService result = super.createWrapper(new BeanId(this, null));


至此,我们终于结束了第一个RMI循环,并得到了Remote接口UserService的Stub类_UserService_Stub,就是#5

里面的result。

这里有一个问题,为什么#4不直接create _UserService_Stub,而又转了一道#5的手呢?因为#4 extends from

EJSWrapper,它没有能力create Stub,因此必须借助#5,which extends from EJSHome,这样才可以生成一个

Stub。如果不是为了生成这个Stub,应该可以不走#5这一步。



第二个RMI循环
OK, now we got the object which is instanceOf _UserService_Stub, and implements UserService

现在我们的Client端走到第三步了:
UserInfo ui = object.getUserInfo(userId);

继续看代码,开始第二个RMI循环:

1. 调用object.getUserInfo()
代码:

UserService object;
object.getUserInfo(userId);


2. 实际是调用_UserService_Stub.getUserInfo(int

arg0),在这个方法里面,Stub向Skeleton发送了一个getUserInfo的字串和arg0这个参数:

代码:

org.omg.CORBA.portable.OutputStream out = _request("getUserInfo", true);
out.write_long(arg0);
in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);


3. Server端的Skeleton接收Stub发来的request,并调用相应的方法:
代码:

_EJSRemoteStatelessUserService_a940aa04_Tie._invoke() {
switch (method.charAt(5))
{
case 83:
if (method.equals("getUserInfo")) {
return getUserInfo(in, reply);
}
......
}
}

_EJSRemoteStatelessUserService_a940aa04_Tie.getUserInfo() {
EJSRemoteStatelessUserService_a940aa04 target = null;
int arg0 = in.read_long();
UserDTO result = target.getUserInfo(arg0);
org.omg.CORBA_2_3.portable.OutputStream out = reply.createReply();
out.write_value(result,UserDTO.class);
return out;
}


4. Skeleton调用的是UserService的Server端实现类的getUserInfo方法
代码:

EJSRemoteStatelessUserService_a940aa04.getUserInfo() {
UserServiceBean _EJS_beanRef = container.preInvoke(this, 0, _EJS_s);
_EJS_result = _EJS_beanRef.getUserInfo(id);
}


最后的最后,#4终于调用了我们写的UserServiceBean里的getUserInfo方法,这才是我们真正想要去做的事情

至此,第二个RMI循环也终于结束了。



调用流程图
回顾一下上面的分析,可以很清晰的看到两次RMI循环的过程,下图(见链接)描述了整个流程:

http://www.pbase.com/image/27229257

黄色的1,6,10是程序员要写的,其余是系统生成的。

#1是Home interface, #2和#4都implements 了它。
#6是Remote interface, #7和#9都implements 了它。
#10是Bean实现。


3:weblogic实现
一个远程对象至少要包括4个class文件:远程对象;远程对象的接口;实现远程接口的对象的stub;对象的ske

leton这4个class文件。

在EJB中则至少要包括10个class:

Bean类,特定App Server的Bean实现类

Bean的remote接口,特定App Server的remote接口实现类,特定App

Server的remote接口的实现类的stub类和skeleton类

Bean的home接口,特定App Server的home接口实现类,特定App

Server的home接口的实现类的stub类和skeleton类

和RMI不同的是,EJB中这10个class真正需要用户编写的只有3个,分别是Bean类和它的remote接口,home接口

,至于其它的7个class到底是怎么生成,被打包在什么地方,或者是否需要更多的类文件,会根据不同的App

Server表现出比较大的差异,不能一概而论。

拿Weblogic的来说吧,Weblogic的Bean实现类,以及两个接口的Weblogic的实现类是在ejbc的时候被打包到EJB

的jar包里面的,这3个class文件可以看到。而home接口和remote接口的Weblogic的实现类的stub类和skeleton

类是在EJB被部署到Weblogic的时候,由Weblogic动态生成stub类和Skeleton类的字节码,因此看不到这4个类

文件。

对于一次客户端远程调用EJB,要经过两个远程对象的多次RMI循环。首先是通过JNDI查找Home接口,获得Home

接口的实现类,这个过程其实相当复杂,首先是找到Home接口的Weblogic实现类,然后创建一个Home接口的Web

logic实现类的stub类的对象实例,将它序列化传送给客户端(注意stub类的实例是在第1次RMI循环中,由服务

器动态发送给客户端的,因此不需要客户端保存Home接口的Weblogic实现类的stub类),最后客户端获得该stu

b类的对象实例(普通的RMI需要在客户端保存stub类,而EJB不需要,因为服务器会把stub类的对象实例发送给

客户端)。

客户端拿到服务器给它的Home接口的Weblogic实现类的stub类对象实例以后,调用stub类的create方法,(在代

码上就是home.create(),但是后台要做很多事情),于是经过第2次RMI循环,在服务器端,Home接口的Weblogic

实现类的skeleton类收到stub类的调用信息后,由它再去调用Home接口的Weblogic实现类的create方法。

在服务端,Home接口的Weblogic实现类的create方法再去调用Bean类的Weblogic实现类的ejbCreate方法,在服

务端创建或者分配一个EJB实例,然后将这个EJB实例的远程接口的Weblogic实现类的stub类对象实例序列化发

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名
注册