转载http://fengshujuan.iteye.com/blog/226993,加了些自己的理解
RMI
Remote Method Invocation,分布式程序的API。它集合了Java序列化和Java远程方法协议(Java Remote Method Protocol)。
实现了夸JVM,操作系统间的java对象调用。RMI目前使用JRMP(Java Remote Messaging Protocol)进行通信
RMI使用stub代理机制,stub需要在远程和本地各存相同的一份。
要使用RMI,必须构建四个主要的类:远程对象的本地接口、远程对象实现、RMI客户机和RMI服务器。RMI服务器生成远程对象实现的一个实例,并用一个专有的URL注册。RMI客户机在远程RMI服务器上查找服务对象,并将它转换成本地接口类型,然后像对待一个本地对象一样使用它。
实例:
1.远程对象的本地接口
import java.rmi.Remote; import java.rmi.RemoteException; public interface Hello extends Remote { // 接口中的具体方法声明,注意必须声明抛出RemoteException String sayHello( String name )throws RemoteException; }
2.远程对象实现类
import java.rmi.RemoteException; import javax.rmi.PortableRemoteObject; public class HelloImpl extends PortableRemoteObject implements Hello { public HelloImpl() throws RemoteException { super(); } public String sayHello(String message) throws RemoteException { System.out.println("我在RMI的服务器端,客户端正在调用'sayHello'方法。 "); System.out.println("Hello " + message); return message; } }
3.RMI服务器类
import java.rmi.Naming; public class HelloServer { public static void main( String[] args ) { // 在服务器端设置安全机制 /* * if (System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); } */ try { System.out.println( "开始 RMI Server ..." ); /* 创建远程对象的实现实例 */ HelloImpl hImpl = new HelloImpl(); System.out.println( "将实例注册到专有的URL " ); Naming.rebind( "HelloService", hImpl ); System.out.println( "等待RMI客户端调用..." ); System.out.println( "" ); } catch ( Exception e ) { System.out.println( "错误: " + e ); } } }
4.RMI客户机类
import java.rmi.Naming; public class HelloClient { public static void main( String[] args ) { // 在服务器端设置安全机制 /* * if (System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); } */ /* 默认为本地主机和默认端口 */ String host = "localhost:1099"; /* 带输入参数时,将host设置为指定主机 */ if ( args.length > 0 ) host = args[0]; try { /* 根据指定的URL定位远程实现对象 */ /* “h”是一个标识符,我们将用它指向实现“Hello”接口的远程对象 */ Hello h = (Hello) Naming.lookup( "rmi://" + host + "/HelloService" ); System.out.println( "实现“Hello”接口的远程对象: " + h ); System.out.println( "我在客户端,开始调用RMI服务器端的'sayHello'方法" ); System.out.println( "欢迎, " + h.sayHello( "javamxj blog" ) ); } catch ( Exception ex ) { System.out.println( "错误 " + ex ); } } }
5. 编译代码与运行系统
在MS-DOS环境下,创建一个D:\RMISample目录,把上面4个文件复制到这个目录下,然后在此目录下新建两个文件夹:client和server(把它们分别看作是客户端与服务端)。
(1).编译所有的源代码
D:\RMISample> javac *.java
(2).生成客户端存根//这将生成HelloImpl_Stub.class
D:\RMISample> rmic HelloImpl
( 注:如果需要查看源代码,可以使用“ rmic -keep HelloImpl”语句)
(3).把Hello.class,HelloClient.class,HelloImpl_Stub.class复制到client目录;
把Hello.class,HelloServer.class,HelloImpl_Stub.class,HelloImpl.class 复制到server目录。
(4).启动RMI注册
D:\RMISample\server>rmiregistry
(注:我是在命令控制台下运行这个系统的,必须开启三个控制台窗口,一个运行RMIRegistry,一个运行服务器,还有一个运行客户端。)
(5).运行和调用
● 在服务器上执行HelloServer
D:\RMISample\server>java HelloServer
● 在本地客户机上运行HelloClient
D:\RMISample\client>java HelloClient
以下未验证:
● 在远程客户机上运行HelloClient(须指明RMI服务器主机名或IP地址)
java HelloClient 222.222.34.34
还有一点要注意,在上面的例子中我注释了安全管理的代码,如果把注释去掉,那么需要建立一个安全策略文件,比如其文件名为 policy.txt,内容如下:
grant {
permission java.security.AllPermission "", "";
};
这是一条简单的安全策略,它允许任何人做任何事,对于你的更加关键性的应用,你必须指定更加详细安全策略。把这个文件复制到Client和Server目录,然后如下运行:
D:\RMISample\server>java -Djava.security.policy=policy.txt HelloServer
D:\RMISample\client>java -Djava.security.policy=policy.txt HelloClient