java的远程方法调用

来源:互联网 发布:mac 水漾润泽 编辑:程序博客网 时间:2024/04/29 21:40

1,前言

        前段时间我从昆明搬家到成都,突然想起还有一个文件落在了昆明,这个文件很重要,该怎么办呢。当然我会不假思索的赶快联系在昆明的朋友,让这个朋友帮我拿到文件,再帮我邮寄过来。本来很棘手而又很重要的一件事,似乎很容易且方便的就解决了。

        当我学习java远程方法调用时,突然明白java的这项技术原来借鉴了日常生活中的经常用到而又很简便的方法。我不妨看作是运行在本地的一个jvm,而在昆明的朋友就是一个远程运行的jvm,我通过调用远程jvm的一个方法(拿文件)得到了期望的服务,这个过程就称作远程方法调用,这项技术是Java分布式技术的基础。这项技术对java是很重要的,例如ejb等分布式应用的开发。

2,运行原理

        联想开篇的例子。很明显需要两个运行的jvm,为了区别,把这两个jvm分别叫做本地jvm和远程jvm。

        对于远程jvm,其是提供服务的一方,因而其先要有一个可供远程调用的方法。考虑到java的面向对象特性,这里使用了一个implements了Remote接口的接口(实现该接口的类,都是一个可以被远程调用的类),然后建立实现了该接口的类(这个类还需要继承UnicastRemoteObject类),这样一个可供远程调用的类就建好了,使用接口是为了向调用这些方法的一方隐藏具体的实现。这只是第一步,我们还要对这个类进行一些处理,以便让其他jvm知道这个类是可以被调用的,以及怎么调用的问题。解决这个问题,就需要把这个类和其url绑定起来。这样远程jvm一方就准备好了。

        对于本地jvm。首先得清楚有那些远程方法可供调用,即要知道远程类的url和名字(由于使用了接口,因而是接口的名字)。然后用Naming.lookup方法来构造这个类的实例,那么就可以使用远程的方法了。

        这样就完了吗?当然不是,不能忽略了邮局和快递公司。既然是远程,两个jvm之间就要通信,所幸的是Naming.lookup以为我们做好了一切的通信工作,所以这里就不讨论了。

        总结起来,java远程调用的运行过程可以分为三步:1)远程服务类(昆明朋友的拿文件方法);2)远程服务类的注册类(得让别人找到嘛);3)本地调用类(调用远程方法)

 

3,实践

        1)远程接口

1.      package com.robin.demo.rmi.interf;  

2.        

3.      import java.rmi.Remote;   

4.      import java.rmi.RemoteException;  

5.        

6.      public interface RmiSample extends Remote {   

7.          public int sum(int a, int b) throws RemoteException;   

8.      }   

 

2)远程类

1.      package com.robin.demo.rmi.impl;  

2.        

3.      import java.rmi.RemoteException;  

4.      import java.rmi.server.UnicastRemoteObject;  

5.        

6.      import com.robin.demo.rmi.interf.RmiSample;  

7.        

8.        

9.      public class RmiSampleImpl extends UnicastRemoteObject implements RmiSample {   

10.       /**  

11.        *   

12.        */  

13.       private static final long serialVersionUID = 2742977636753958461L;  

14.     

15.       public RmiSampleImpl() throws RemoteException {   

16.           super();   

17.       }   

18.     

19.       public int sum(int a, int b) throws RemoteException {   

20.           return a + b;   

21.       }   

22.     

23.   }   

 

3)注册类

1.      package com.robin.demo.rmi.server;  

2.        

3.      import java.net.MalformedURLException;  

4.      import java.rmi.Naming;   

5.      import java.rmi.RemoteException;  

6.      import java.rmi.registry.LocateRegistry;  

7.        

8.      import com.robin.demo.rmi.impl.RmiSampleImpl;  

9.        

10.     

11.   public class RmiSampleServer {   

12.     

13.       /**  

14.        * @param args  

15.        */  

16.       public static void main(String[] args) {  

17.           try{   

18.               LocateRegistry.createRegistry(8808);  

19.               RmiSampleImpl server= new RmiSampleImpl();   

20.               Naming.rebind("//localhost:8808/SAMPLE-SERVER" , server);   

21.           }catch (MalformedURLException me){  

22.               System.out.println("Malformed URL: " + me.toString());   

23.           }catch(RemoteException re){   

24.               System.out.println("Remote Exception: "+re.toString());   

25.           }  

26.       }   

27.     

28.   }   

 

4)本地调用远程方法

1.      package com.robin.demo.rmi.client;  

2.        

3.      import java.rmi.Naming;   

4.      import java.rmi.RemoteException;  

5.        

6.      import com.robin.demo.rmi.interf.RmiSample;  

7.        

8.        

9.      public class RmiSampleClient {   

10.     

11.       /**  

12.        * @param args  

13.        */  

14.       public static void main(String[] args) {  

15.           try {   

16.               String url = "//localhost:8808/SAMPLE-SERVER";   

17.               RmiSample RmiObject = (RmiSample) Naming.lookup(url);  

18.               System.out.println(" 1 + 2 = " + RmiObject.sum(1, 2));  

19.           } catch (RemoteException rex) {  

20.               System.out.println("Error in lookup: " + rex.toString());   

21.           } catch (java.net.MalformedURLException me) {  

22.               System.out.println("Malformed URL: " + me.toString());   

23.           } catch (java.rmi.NotBoundException ne) {  

24.               System.out.println("NotBound: " + ne.toString());   

25.           }  

26.     

27.       }   

28.     

29.   }   

 

4,后记

        本文是有感而发写成的。在一些细节方面不是很深入,若想深入研究,可以从两方面着手,一是对java的socket通信机制和java.rmi的源码研究;二是对ejb等分布式开发方面的学习。总之学无止境………

5,参考文章
<1>java远程方法调用(RMI),http://robinjie.iteye.com/blog/34606
<2>java远程方法调用(Remote Method Invocation,RMI),http://www.blogjava.net/yruc/archive/2007/01/11/93215.html


原创粉丝点击