计划提纲:引入→RMI概念→RMI HelloWorld程序→RMI-IIOP→RMI-IIOP HelloWorld程序
Part One:引入
从一幅图开始:
上图说明的是client端程序访问远程服务器上EJB的详细流程,这里我主要要关注的是底层实现技术RMI-IIOP,同样
中第四部分开始也说明客户端与JBOSS EJB组件系统的交互中RMI-IIOP的重要性,所以研究EJB学习RMI-IIOP是非常有必要的,Java RMI-IIOP(java remote method invocation over the internet inter-ORB protocol),如果使用过RMI,就应该很清除RMI是Java执行远程方法调用的方式,而RMI-IIOP则是RMI的功能扩展版本,增加了如:分布式垃圾收集,对象活化,可下载类文件等,所以你可以把RMI理解成为RMI-IIOP的简化版本,在分布式对象方法调用上他们都完成了最基本的功能,综上,理解RMI-IIOP之前需要理解RMI,所以开始我们的Part two.
Part Two: RMI概念原理
RMI(Remote Method Invocation):JDK提供的一个完善的、简单易用的远程方法调运框架,它要求服务器端和客户端都是Java程序。这句话说明:
1 Java所特有的分布式计算技术
2 允许运行在一个Java虚拟机上的对象调用运行在另一个Java虚拟机上的对象的方法,从而使Java编程人员可以方便地在网络环境中作分布式计算
3 面向对象设计要求每个任务由最适合该任务的对象执行,RMI将这个概念更深入了一步,使任务可以在最适合该任务的机器上完成
区别两个概念来说明RMI
RMI | RPC | |
全名 | Remote Method Invocation | Remote Procedure Call Protocol |
速度 | 低速 | 高速 |
可靠性 | 可靠 | 不可靠 |
底层协议 | TCP/IP | UDP |
说明:其实这两个名词没有可比性,因为他们根本不是一类东西,RMI是Sun公司定义的一个Java分布式框架,包括一些Java接口等,而RPC是一个网络协议;
RMI框架的基本结构:
1 Client 表示客户端java程序
2 Server 表示服务器端java程序
3 Stub就是代表远程对象的客户方代理,定义远程对象版本所支持的所有接口
4 Remote Referance表示远程引用层简称RRL
5 Skeletons是与服务器方代理,接受客户机方RRL的方法调用请求
6 底层是基于TCP/IP的协议
客户端调用远程服务器程序,先调用本地stub的方法,而本地stub将负责执行对远程对象的方法调用。在RMI中,远程对象的代理stub与该远程对象所实现的远程接口集相同,当你使用RMI来开发一个分布式应用时,需要遵守下面的步骤:
定义远程接口:一个远程接口定义了可以被客户端远程调用的方法。
实现远程对象:远程对象必须实现一个或多个远程接口。
注册远程对象:RMI采用的是命名和目录服务,所以远程对象注册后,客户端才可以访问
实现客户端:使用远程对象的客户可以在远程接口被定义后的任何时候实现。
Part Three: RMI HelloWorld 程序
1 创建远程接口,需要注意两点:实现java.rmi.Remote接口,接口中所有方法抛出java.rmi.RemoteException;
如下代码HelloService为远程接口
public interface Service { public String echo(String msg) throws RemoteException; public Date getTime() throws RemoteException; }
public interface HelloService extends Service, Remote { }
2 创建远程对象,同样注意两点:实现远程接口、继承java.rmi.server.UnicastRemoteObject类,如下HelloServiceImpl为远程对象
public class HelloServiceImpl extends UnicastRemoteObject implements HelloService { private String name; public HelloServiceImpl(String name) throws RemoteException { this.name = name; } public String echo(String msg) throws RemoteException { return "echo: " + msg + " from " + name; } public Date getTime() throws RemoteException { return new Date(); } }
3 注册远程对象,如下HelloServer注册了远程对象:
public class HelloServer { public static void main(String[] args) { try { HelloService helloWorld = new HelloServiceImpl("kylinsoong"); LocateRegistry.createRegistry(8888); Naming.bind("rmi://localhost:8888/helloWorld",helloWorld); } catch (RemoteException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (AlreadyBoundException e) { e.printStackTrace(); } } }
4 客户端程序,下面HelloClient程序:
public class HelloClient { public static void main(String[] args) { try { HelloService helloworld = (HelloService) Naming.lookup("rmi://localhost:8888/helloWorld"); System.out.println(helloworld.echo("kylin soong") + "\n" + helloworld.getTime()); } catch (MalformedURLException e) { e.printStackTrace(); } catch (RemoteException e) { e.printStackTrace(); } catch (NotBoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }
运行服务器端远程对象注册完成后,运行客户端代码可以出现如下结果;
echo: kylin soong from kylinsoong Tue Nov 02 21:22:46 CST 2010
Part Four: RMI-IIOP概念与原理
Part Five: RMI-IIOP HelloWorld 程序