【java】itoo项目实战之EJB中的RMI框架

    在上篇博客<<itoo中为什么要用EJB3.0分布式框架>>中介绍了itoo是一个了EJB容器,同时也是用到了RMI框架的远程方法调用.这一节就介绍一下RMI这个框架.

    EJB的方法调用框架,它适合不同种类的远程客户端.客户端通过框架和EJB服务实现交互,从而可以快速有效地开发出一个强大的,可分布式的可伸缩的企业应用或专用系统.

远程调用技术背景

    C/S多层结构首先需要解决的问题是:肥客户端和服务器之间的远程通信和调用。远程调用的概念由来已久,Java RMI Remote Method Invocation远程方法调用)是远程方法调用的简称,它大大增强了Java开发分布式应用的能力。

    所谓远程方法调用,就是在一台机器上调用另外一台机器上对象的方法。正如前面章节所讨论的,客户端调用EJB一般是通过RMI方式进行的。这样,EJB能以分布式运行在多台服务器之间,对于客户端的调用是透明的,几乎没有什么区别。

    RMI所提供的远程方法调用是有一定限制的,即“远程”并不意味着非常远,一般是指在同一个防火墙内的区域。因为实际应用中,网络防火墙因为安全原因,对大多数协议或端口都进行了封锁,在这种情况下,防火墙以外的客户端如果希望通过RMI调用EJB服务,那几乎是不可能的事情,因此,需要寻找一个能穿透大多数防火墙的协议,将远程客户端调用导入防火墙内部,再通过RMI调用EJB服务。

    目前,HTTP协议大概是惟一的防火墙友好的协议。其实,Web ServiceSOAP也是一种基于HTTP协议的协议。

    这样,针对B/S多层结构,因为一般Web服务器和EJB服务器是位于同一个防火墙内,属于一个局域网;因此,Web服务器作为客户端可以通过RMI实现EJB服务的远程方法调用;而针对C/S多层结构,将客户端的调用通过HTTP协议序列化后导入防火墙的Web服务器内,再通过Web服务器实现EJB服务的RMI调用。

  框架结构

7-1展示了该框架系统在两种体系结构(B/SC/S)下的应用架构:


    在图中,客户端主要负责处理视图显示、事件控制响应、发出HTTP请求。ServletProxy专门用于接受HTTP请求,通过Business Proxy调用EJB Service

    如果客户端是浏览器这样的瘦客户端,那么通过RMI就可以直接调用EJB了。不过,在本框架系统中,调用EJB是通过方法反射机制来实现的,而不是通常的EJB调用方式.

    图的虚线包括的部分是EJB方法调用框架。可以发现,通过使用该框架系统,实现了EJB和客户端之间的解耦,两者各自变成一个相当独立的子系统,利于开发和维护。

    对于Web开发人员,无需掌握太多EJB相关知识,只要获知EJB Service提供的功能方法,就可以相对独立地开发Servlet/JSP;也无需在Web层进行EJB出错捕获等琐碎工作;可以在没有EJB容器或数据服务器情况下测试Web层。 

    对于EJB开发人员,也无需了解StrutsWeb技术,EJB改变或部署变化时,不必变动Web层代码。

    由于该框架系统对EJB Service实现了缓存机制,大大提高了系统响应性能,如果再结合具体数据缓存机制,整个系统的并发处理性能将提高很多。

 

.类的详细设计和实现

    框架中比较复杂的是远程客户端对EJB方法调用。在这些具体流调用环节中,将要使用动态代理模式、通过HTTP实现对象序列化和反序列化、基于HTTP的安全验证以及EJB反射方法等技术。

    以肥客户端/服务器体系为例,肥客户端通过本框架系统获得EJB的代理实例后,启动EJB的方法调用,动态代理机制将调用的方法名、参数类型和参数数值进行打包序列化,向远程J2EE服务器发出HTTP的请求。

具体实现的类关系图如图所示。


在图7-4中,Client作为本框架系统的应用客户端,主要是调用动态代理工厂ServiceClientFactoryServiceClientFactory封装了所有远程调用细节。ServiceFactoryImp作为ServiceClientFactory的实现子类,实际上主要功能实现还是依赖动态代理API中的RemoteInvocationHandlerinvoke方法,而RemoteInvocationHandler又将远程调用实现委托给了HTTP客户端HTTPClient,通过HTTPClient与远程J2EE服务器的HTTPServlet发生交互。在HTTPClient中,根据需要发出HTTPRequest请求,从服务器获得的响应是HTTPResponse

.基本业务对象

    在上图中,框架的应用客户端直接调用ServiceClientFactory,获得所要调用EJB的动态代理,以用户安全管理系统为例,要获得当前用户资料的客户端代码如下:

/获得EJB定义实例
EJBDefinitionSecurityFacade = new EJBDefinition(
     "java:comp/env/ejb/EJBContollerLocal",
     "com.jdon.security.auth.ejb.SecurityFacadeLocal");
//获得ServiceClientFactory单态类
ServiceClientFactoryserviceFactory = ServiceClientFactory.getInstance();
//获得EJB SecurityFacadeLocal动态代理实例
SecurityFacadeLocalsecurityFacadeLocal =
         (SecurityFacadeLocal) serviceFactory.getService(SecurityFacade);
//直接调用远程EJB SecurityFacadeLocal的方法getUser()
Useruser = securityFacadeLocal.getUser();

上面是一个框架应用客户端调用本框架的具体代码,通过这段代码,这个客户端应该能获得远程服务器中当前用户资料。

    在上面客户端代码中需要将有关EJB的定义信息传送到服务器端,因此本框架系统的第一个基本业务对象(Domain Object)就是EJB的定义信息,它主要是保存着EJB的两个主要数据JNDI名和EJB本地接口名。它在客户端生成后,将通过本框架系统一直传送到J2EE服务器的EJB调用层。

定义EJBDefinition的代码如下(程序1):

程序1

publicclass EJBDefinition implements Serializable {
 private String _jndiName;
 private String _local;
 public EJBDefinition(String p_jndiName, String p_localClassName) {
   _jndiName = p_jndiName;
   _local = p_localClassName;
  }
 public Class getEJBInterfaceClass() {
       return getLocalClass();
  }
 public Class getLocalClass() {
   try {
     return Class.forName(_local);
   } catch (ClassNotFoundException ex) {
     throw new RuntimeException("Unable to load the class : " + _local);
   }
  }
 public String getLocalName() {    return _local;  }
 public String getJndiName() {    return _jndiName;  }
}


除了EJBDefinition之外,客户端调用的EJB方法名称、参数类型以及参数数值都应该属于基本业务对象,因为它们的实现是使用动态代理API.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

弯_弯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值