EJB方法调用框架
本章将介绍一种EJB方法调用框架,它使得组装业务功能的EJB适合专门的远程客户端调用,如Java Application、Applet或J2ME等客户端。这些客户端通过本框架和EJB服务实现交互,从而可以形成基于C/S(客户端/服务器)模式的多层结构系统。
本框架framework是通过Java的动态代理机制实现,而目前很多AOP(面向方面编程)框架也是基于动态代理机制实现,因此通过本框架的研发可有帮于掌握AOP原理。
7.1 框架概况
J2EE多层结构根据客户端形式的不同,分为两种主要形式,客户端基于浏览器的B/S多层结构和基于肥客户端的C/S多层结构。后者在一些专业专用领域有一定的应用市场,特别是Java无线技术的发展,J2ME作为一个拥有功能强大的手机终端系统正显现其特有的魅力。
使用肥客户端技术可以减轻J2EE服务器系统的操作开销,降低客户端和服务器端的通信次数,提供交互层次,改善数据的确认速度,缺点是需要用户专门下载安装。
7.1.1 远程调用技术背景
C/S多层结构首先需要解决的问题是:肥客户端和服务器之间的远程通信和调用。远程调用的概念由来已久,Java RMI (Remote Method Invocation
远程方法调用)是远程方法调用的简称,它大大增强了Java开发分布式应用的能力。
所谓远程方法调用,就是在一台机器上调用另外一台机器上对象的方法。正如前面章节所讨论的,客户端调用EJB一般是通过RMI方式进行的。这样,EJB能以分布式运行在多台服务器之间,对于客户端的调用是透明的,几乎没有什么区别。
RMI所提供的远程方法调用是有一定限制的,即“远程”并不意味着非常远,一般是指在同一个防火墙内的区域。因为实际应用中,网络防火墙因为安全原因,对大多数协议或端口都进行了封锁,在这种情况下,防火墙以外的客户端如果希望通过RMI调用EJB服务,那几乎是不可能的事情,因此,需要寻找一个能穿透大多数防火墙的协议,将远程客户端调用导入防火墙内部,再通过RMI调用EJB服务。
7.1.2 框架结构
在前面章节中也讨论了一种接口框架系统的设计,本框架是在其基础上再进行深入和抽象。同时兼顾到远程肥客户端的调用情况,更加提高了系统的可重用性以及可伸缩性,加快了系统开发进程。
7.2 框架设计
7.2.1 代理(Proxy)模式
在GOF设计模式中对代理模式的定义是:为其他对象提供一种代理,以控制对这个对象的访问。代理模式可以强迫客户端对一个对象的方法调用间接通过代理类进行。
通常代理模式有以下几种:访问代理(Access Proxy)、虚拟代理和远程代理等。
访问代理是对访问服务或数据对象实现安全权限控制,如Jive论坛中的代理模式就属于这种。
虚拟代理可实现对象不同方式的初始化,具体有两种方式:即时的和懒惰的,懒惰初始化是相对即时初始化而言,它不是在这个对象生成时立即进行初始化工作,而是只在被访问使用时的才进行初始化。
远程代理是用于屏蔽或保护客户端离开远距离的原始对象,当客户端访问一个对象需要经过漫长的网络调用或大数据读写时,可以通过在本地设置中间代理来代替远程的原始对象。
7.2.2 动态代理
动态代理(Dynamic Proxy)是JDK 1.3以后推出的新API,它是代理模式的一种高级实现,可以更加彻底地解耦调用者和被调用者之间的关系,动态代理利用Java的反射(Reflect)机制,可以在运行时刻将一个对象实例的方法调用分派到另外一个对象实例的调用,这种类似中途拦截的原理通常被AOP框架用来作为拦截器(Interceptor)实现,掌握动态代理是理解AOP框架原理的重要初始环节。
7.2.3 反射(Reflection)和方法
上节的Proxy.newProxyInstance属于Java反射(Reflection)的一种实现,除此之外,反射还有字段Field、方法Method等实现,Java反射机制是一种提供了类安全的,支持类和对象自省机制的API。
这样,通过客户端的动态代理机制和服务器端的方法反射机制,就可以完成远程客户端对服务器EJB Service的访问。那么,如何将远程客户端调用的EJB方法名、参数类型和参数数值传送到服务器端。
7.2.4 Http协议和对象序列化
HTTP协议是一种请求/应答式的协议。以浏览器为例,当浏览器发送一个请求,在后台建立一个连接到服务器80端口的基于Socket的TCP连接,服务器处理后,返回该请求的应答。HTTP协议最新的版本是HTTP/1.1,HTTP/1.1由
RFC 2616 定义。
7.2.5 框架设计图
7.2.6 HttpSession和缓存机制
尽管在J2SE 1.4以后版本中,Java的反射机制性能得到了很大提高。但是在实际运行中,还是需要通过缓存Cache来进一步提高性能。
考察本系统有两处需要实现缓存:
一个是Proxy.newProxyInstance生成的动态对象实例,如果每次都使用这条反射语句获得动态对象实例,显然会影响速度,可以在第一次生成动态对象实例后将其保存起来,下次需要该对象实例时从缓存中获取。
另外一处是EJBLocalObject或EJBObject实例的生成,当EJB创建后,调用该EJB的客户端拥有一个指向EJBLocalObject或EJBObject的引用。
7.2.7 基于Http的安全机制
从前面章节“用户安全管理系统”中已经知道,对用户名和口令进行拦截验证有两种主要方式:一种是使用容器的安全验证机制,如基于HTTP的验证登录机制;还有一种是自己实现用户名和口令的验证。可以根据实际情况进行两种方式的选用。
7.3 类的详细设计和实现
以肥客户端/服务器体系为例,肥客户端通过本框架系统获得EJB的代理实例后,启动EJB 的方法调用,动态代理机制将调用的方法名、参数类型和参数数值进行打包序列化,向远程J2EE服务器发出HTTP的请求。
7.3.1 基本业务对象
7.3.2 动态代理工厂
7.3.3 肥客户端/服务器架构下实现
7.3.4 Web层代理Sevlet
Proxy
7.3.5 浏览器/服务器架构下实现
7.3.6 核心代理Business Proxy实现
框架核心部分主要是在Business Proxy中实现,尽管向Business Proxy发出请求可能来自两种客户端,但是Business
Proxy无需进行这种区别,只要知道它们都是进行EJB服务调用请求的。
Business Proxy由两大部分组成:HTTPSession缓存处理和EJB方法调用。
ComponentManager是HTTPSessionBindingListener的一个实现者,是一个HTTPSession的监视器。其作用是能够在HTTPSession超时失效或用户退出调用removeAttribute方法时,自动激活valueUnbound(HTTPSessionBindingEvent
event)方法。在这个方法中,实现EJBObject引用清除工作,将那些曾经被保存到HTTPSession中的EJBObject清除干净。这样,垃圾回收机制能够回收这些EJBObject,无疑可以提高内存使用性能,防止内存泄漏。
7.4 框架的使用和调试
7.4.1 配置
7.4.2 浏览器/服务器架构下的应用
7.4.3 肥客户端/服务器架构下的应用
7.5 小结
章主要介绍了一种EJB调用框架,通过Java的方法(Method)反射机制直接调用EJB方法。这种框架的最大优点是隔离了Web层和EJB层,实现了两者的完全解耦,简化了EJB服务的调用结构。
在中大型系统中,由于系统功能的复杂,导致实现这些功能的EJB数量剧增。同时,一个功能的完全实现常常是贯穿于Web层和EJB层,客户端通过Web层调用EJB方式可能有多种形式。最通常的情况是,Web层调用一个EJB
Facade类,通过这个Facade再调用其他EJB,这种模式在EJB数量巨大的情况下,会导致系统调用混乱。有时除了开发者本人掌握调用的来龙去脉外,其他人很难了解其中的调用路径,犹如走入迷宫,这种情况必然导致系统的可维护性和可拓展性降低。
|