RMI初步

  RMI(remote method Invocation)自从Java1.1便出现了,是Java之间远程调用的基础,EJB便是构建在其基础上的。但只能是Java对象之间的RPC,不支持异构系统调用。当然,异构系统之间的调用我们一般用WebServices(在通信、金融行业也有广泛使用重量级的CORBA作为解决方案)。其实无论是异构系统的RPC还是JVM之间的RMI,核心思想都是类似的,主要是Stub和Skeleton对象在近端和远端充当中介。在RMI中这两个对象在底层处理了,对程序员是透明的。我们使用一个简单的例子描述RMI的简单使用方法,下一篇文章我们描述项目中一个真实的应用:Flex+RMI开发的一个简单的自动化部署工具。用于将程序快速发布到数十台集群机器上。
OK,我们先看简单的demo(代码是在记事本中手写的,注释不全请海涵):
1、远程对象接口,在Client端依赖查找到的也是接口类型:

import java.rmi.Remote;
import java.rmi.RemoteException;

//远程对象接口
public interface Bean extends Remote{

    public String sayHello()throws RemoteException;

    public String sayHello(String name)throws RemoteException;
};

2、远程对象实现类

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

//远程对象实现类
public class BeanImpl extends UnicastRemoteObject implements Bean{

    public BeanImpl()throws RemoteException { };

    public String sayHello(){
        return "hello!";
    }

    public String sayHello(String name){
        return "hello,"+name+"!";
    }
};

3、Server端

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.Naming;

public class Server{
    public static void main(String []args)throws Exception{
        //构造待调用的远端对象,注册端口并绑定     
        Bean bean = new BeanImpl();
        LocateRegistry.createRegistry(8888);
        String url = "//127.0.0.1:8888/server";
        Naming.bind(url,bean);
    }
};

4、Client端类:

import java.rmi.Naming;

public class Client{
    public static void main(String []args)throws Exception{
        String url = "//192.168.1.145:8888/server";
        System.out.print("查找地址为"+url+"的对象:");
        Bean bean = (Bean)Naming.lookup(url);
        System.out.println(bean);
        System.out.println("调用远程对象无参方法:"+bean.sayHello());
        System.out.println("调用远程对象有参方法:"+bean.sayHello("digitalChina"));
    }
};

 

演示:
1、将Server.java、Bean.java、BeanImpl.java 在一个内网ip为192.168.1.145的机器上编译(我用命令行javac),然后java Server运行起来(此时RMI底层已经在8888端口监听了)
2、将Client.java、Bean.java在内网ip为192.168.1.112的另一台机器上编译,然后执行java Client。

上面的代码我们可以看见,在Client的main方法中,我们使用RMI获取了一个Bean接口类型的对象,然后调用了两次该对象的方法:

从上面的输出我们可以看出,使用Naming.lookup查找到的是代理对象Proxy。

如果遇到access denyed异常,则可能是JDK对server端安全控制的问题,需在起Server的时候指定安全策略:

[root@localhost RMISERVER]# java -Djava.security.policy=rmi.policy Server &

其中rmi.policy的内容

grant {
permission java.net.SocketPermission "*:8888","connect,accept,resolve";
};

 


OK,至此,一个简单RMI的demo就这样Run起来了。下一篇文章《近两年项目回顾系列——基于Flex和RMI的自动化部署工具 》大体描述一下我们基于RMI开发的一个自动化部署小工具。

posted @ 2013-05-30 15:56  大树的博客  Views(402)  Comments(0Edit  收藏  举报