在上一篇学习dubbo时 提到RMI,远程调用,下面找了篇不错的文章 学习下:http://6221123.blog.51cto.com/6211123/1112619


Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用应用程序编程接口。它使客户机上运行的程序可以调用远程服务器上的对象。远程方法调用特性使Java编程人员能够在网络环境中分布操作。RMI全部的宗旨就是尽可能简化远程接口对象的使用。

Java RMI极大地依赖于接口。在需要创建一个远程对象的时候,程序员通过传递一个接口来隐藏底层的实现细节。客户端得到的远程对象句柄正好与本地的根代码连接,由后者负责透过网络通信。这样一来,程序员只需关心如何通过自己的接口句柄发送消息。

接口的两种常见实现方式是:最初使用JRMP(Java Remote Message Protocol,Java远程消息交换协议)实现;此外还可以用与CORBA兼容的方法实现。RMI一般指的是编程接口,也有时候同时包括JRMP和API(应用程序编程接口),而RMI-IIOP则一般指RMI接口接管绝大部分的功能,以支持CORBA的实现。

最初的RMI API设计为通用地支持不同形式的接口实现。后来,CORBA增加了传值(pass by value)功能,以实现RMI接口。然而RMI-IIOPJRMP实现的接口并不完全一致。

这里讲述的是基于JDK1.5的RMI程序搭建,更简单的说是一个 HelloWorld RMI。

1. 这里是基于JDK1.5的,节省了繁琐的手工编译(生成桩和骨架)。不像1.4之前的RMI。

2. 这里是把客户端和服务器端的两个程序,分布在两个独立的程序里面,而不是同一个package下面。是真正的分布式。

3. 这里不过多阐述原理,这只是一个Hello World!!

好,以下是步骤:

1. 在Eclipse里面创建一个server 端的project。然后,创建一个接口,这个接口是你要向client端开放的方法定义。它叫做:UserManagerInterface,而且必须继承Remote接口。


1. package dataserver.rmi.stub; 
2.  
3. import java.rmi.Remote; 
4. import java.rmi.RemoteException; 
5.  
6. import dataserver.rmi.bean.Account; 
7.  
8. public interface UserManagerInterface extends Remote{ 
9. public String getUserName() throws RemoteException; 
10. public Account getAdminAccount() throws RemoteException; 
11. }


2. 为了证明RMI中,“面向对象”或者是“无缝传递JAVA Object”是何等简单,我们需要定义一个Account类,该类是一个Bean,必须实现implements Serializable序列化接口。这是一个可以在client和server传输的可序列化对象。


    1. package dataserver.rmi.bean; 
    2.  
    3. import java.io.Serializable; 
    4.  
    5. public class Account implements Serializable,Cloneable{ 
    6.  
    7. /**
    8.      * 
    9.      */ 
    10. private static final long serialVersionUID = -1858518369668584532L; 
    11. private String username; 
    12. private String password; 
    13.      
    14. public String getUsername() { 
    15. return username; 
    16.     } 
    17. public void setUsername(String username) { 
    18. this.username = username; 
    19.     } 
    20. public String getPassword() { 
    21. return password; 
    22.     } 
    23. public void setPassword(String password) { 
    24. this.password = password; 
    25.     } 
    26.       
    27. }


    3. 此时,需要实现你已经开放的接口:

    1. package dataserver.rmi; 
    2.  
    3. import java.rmi.RemoteException; 
    4.  
    5. import dataserver.rmi.bean.Account; 
    6. import dataserver.rmi.stub.UserManagerInterface; 
    7.  
    8. public class UserManagerImpl implements UserManagerInterface { 
    9.  
    10. public UserManagerImpl() throws RemoteException { 
    11. //super(); 
    12. // TODO Auto-generated constructor stub 
    13. //UnicastRemoteObject.exportObject(this); 
    14.     } 
    15.  
    16. /**
    17.      * 
    18.      */ 
    19. private static final long serialVersionUID = -3111492742628447261L; 
    20.  
    21. public String getUserName() throws RemoteException { 
    22. // TODO Auto-generated method stub 
    23. return "Tommy Lee"; 
    24.     } 
    25.  
    26. public Account getAdminAccount() throws RemoteException { 
    27. // TODO Auto-generated method stub 
    28. new Account(); 
    29. "admin"); 
    30. "admin"); 
    31. return account; 
    32.     } 
    33.  
    34. }


    4. 定义一个主程序入口,注册你已经实现的RMI接口,包括开放端口等。其实很简单:

    把我们的接口名称,命名为“userManager”,方便client进行调用

    1. package dataserver.entry; 
    2.  
    3. import java.rmi.AlreadyBoundException; 
    4. import java.rmi.RemoteException; 
    5. import java.rmi.registry.LocateRegistry; 
    6. import java.rmi.registry.Registry; 
    7. import java.rmi.server.UnicastRemoteObject; 
    8.  
    9. import dataserver.rmi.UserManagerImpl; 
    10. import dataserver.rmi.stub.UserManagerInterface; 
    11.  
    12. public class Entry { 
    13.  
    14. public static void main(String []args) throws AlreadyBoundException, RemoteException{ 
    15.      
    16.  
    17. new UserManagerImpl(); 
    18. 0); 
    19. // Bind the remote object's stub in the registry 
    20. 2001); 
    21. "userManager", userManagerI); 
    22. "server is ready"); 
    23.     } 
    24. }

     

    5. Server端的代码已经全部写完,但是还要把bean类(Account)和接口类(UserMangerInterface)打包成jar,以便可以在下面导入进client端的项目中。

    项目--》右键--》导出--》jar--》选择bean和interface--》命名为RmiServerInterface.jar--》finish

    6.  开始创建client端的程序。新建一个project。创建完成后,把刚才jar包导入进client的项目中。

    7.  导入我们的接口jar以后,可以开始编写一个client端的主程序,并调用server端的方法。

    1. package weiblog.rmi; 
    2. import java.rmi.NotBoundException; 
    3. import java.rmi.RemoteException; 
    4. import java.rmi.registry.LocateRegistry; 
    5. import java.rmi.registry.Registry; 
    6.  
    7. import dataserver.rmi.stub.UserManagerInterface; 
    8.  
    9. public class Entry2 { 
    10.  
    11. public static void main(String []args){ 
    12.          
    13. try { 
    14. "localhost",2001); 
    15. "userManager"); 
    16. ""+userManager.getAdminAccount().getUsername() 
    17.                     +userManager.getAdminAccount().getPassword()); 
    18. catch (RemoteException e) { 
    19. // TODO Auto-generated catch block 
    20.             e.printStackTrace(); 
    21. catch (NotBoundException e) { 
    22. // TODO Auto-generated catch block 
    23.             e.printStackTrace(); 
    24.         } 
    25.          
    26.     } 
    27. }


    8. 启动server端的主程序,然后启动client端的主程序。

    server控制台打印:server is ready

    client控制台打印:adminadmin

    大功告成!!