RMI深度结论

Java RMI 指的是长途方法调用 (Remote Method
Invocation)。它是一种体制,能够让在有些 Java 设想机上的对象调用另一个Java
设想机中的对象上的方式。能够用此格局调用的任何对象必得贯彻该远程接口。RMI是java的远端调用机制的达成。即RMI是一组JAVA语言完结RPC的API。

转载:

在这几个JVM中通过RMI能够调用其余JVM中指标的格局。不管是那台Computer上JVM依旧其余任何计算机上的JVM。RMI的最底层是采取了TCP/IP左券进行通讯的。基于JAVA中的BIO完成的。

 

  1. 客商端通过socket发送rmi哀告”rmi://127.0.0.1:1099/action”
  2. 顾客端得到重临的一串二进制码,那么些是服务端对象的类别化。
  3. 客户端将二进制码反连串为对象。
  4. 顾客端本地调用对象的主意。
  5. 客商端RMI底层进行通讯将转移的指标更新到服务端。

Java RMI 指的是远程方法调用 (Remote Method
Invocation)。它是一种机制,能够让在某些 Java 虚构机上的指标调用另叁个Java
虚构机中的对象上的点子。能够用此方法调用的别的对象必需落成该远程接口。

 

  1. 规划远程调用的接口(如IKoleosmiAction),该接口必得在服务端和客户端都要有。
  2. 概念可实例化的对象的类(如ENCOREmiActionImpl),能够平素承接UnicastRemoteObject
  3. 达成远程方法接口。
  4. 注册RMI端口LocateRegistry.createRegistry;
  5. 伺机接收rmi央求Naming.rebind(“rmi://127.0.0.1:1099/hello”, action);

Java
RMI不是何等新才具(在Java1.1的时期皆有了),但却是是不行首要的底部本领。

永利集团304com,盛名的EJB都以构建在rmi基础之上的,未来还应该有一对开源的长途调用组件,其底层手艺也是rmi。

  1. 发送乞求,获得对象I凯雷德miAction action=(IEscortmiAction)
    Naming.lookup(“rmi://127.0.0.1:1099/hello”);
  2. 调用方法action.add();

 

RMI远程调用方法接口

在用力鼓吹Web Service、SOA的一时,是或不是每一个应用都应当选择古板的Web
瑟维斯组件来落实,通过对照测量试验后,RMI是最简便的,在一些小的行使中是最合适的。

 public interface IRmiAction extends Remote{ public int add() throws RemoteException;}

 

指标实例以及服务端

下面通过一个大致的例子来表明RMI的原理和动用,上边那几个例子是二个轻易易行HelloWorld,但已包罗RMI的主导应用与支出格局。

public class RmiActionImpl extends UnicastRemoteObject implements IRmiAction{ private static final long serialVersionUID = -2241003422571775103L; private int total=0; protected RmiActionImpl() throws RemoteException { super(); // TODO Auto-generated constructor stub } @Override public int add() throws RemoteException { // TODO Auto-generated method stub total++; return total; } public int getTotal(){ return total; } public static void main(String[] args) { try { LocateRegistry.createRegistry; IRmiAction action=new RmiActionImpl(); Naming.rebind("rmi://127.0.0.1:1099/hello", action); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}

 

顾客端调用

/** 
* Created by IntelliJ IDEA. 
* User: leizhimin 
* Date: 2008-8-7 21:50:02 
*
定义叁个远程接口,必得一而再Remote接口,个中要求长途调用的艺术必得抛出RemoteException分外 
*/ 
public interface IHello extends Remote { 

public class RmiActionClient { public static void main(String[] args) { try { IRmiAction action=(IRmiAction) Naming.lookup("rmi://127.0.0.1:1099/hello"); System.out.println(action.add; } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NotBoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}

    /** 
     * 轻便的回到“Hello World!”字样 
     * @return 返回“Hello World!”字样 
     * @throws java.rmi.RemoteException 
     */ 
    public String helloWorld() throws RemoteException; 

    /** 
     * 三个简易的事体方法,依照传入的真名再次来到相应的问候语 
     * @param someBodyName  人名 
     * @return 再次回到相应的致敬语 
     * @throws java.rmi.RemoteException 
     */ 
    public String
sayHelloToSomeBody(String someBodyName) throws RemoteException; 
}

 

/** 
* Created by IntelliJ IDEA. 
* User: leizhimin 
* Date: 2008-8-7 21:56:47 
* 远程的接口的落到实处 
*/ 
public class HelloImpl extends UnicastRemoteObject implements IHello { 
    /** 
     *
因为UnicastRemoteObject的构造方法抛出了RemoteException至极,因而这里暗中同意的构造方法必需写,必须注解抛出RemoteException相当 
     * 
     * @throws RemoteException 
     */ 
    public HelloImpl() throws RemoteException { 
    } 

    /** 
     * 不难的归来“Hello World!”字样 
     * 
     * @return 返回“Hello World!”字样 
     * @throws java.rmi.RemoteException 
     */ 
    public String helloWorld() throws RemoteException { 
        return “Hello World!”; 
    } 

    /** 
     * 三个简练的职业方法,依据传入的全名再次来到相应的问讯语 
     * 
     * @param someBodyName 人名 
     * @return 再次来到相应的问候语 
     * @throws java.rmi.RemoteException 
     */ 
    public String
sayHelloToSomeBody(String someBodyName) throws RemoteException { 
        return “你好,” + someBodyName + “!”; 
    } 
}

 

/** 
* Created by IntelliJ IDEA. 
* User: leizhimin 
* Date: 2008-8-7 22:03:35 
* 制造RMI注册表,运转RMI服务,并将长途对象注册到RMI注册表中。 
*/ 
public class HelloServer { 
    public static void main(String args[]) { 

        try { 
            //创立八个长距离对象 
            IHello rhello = new HelloImpl(); 
            //本地主机上的长距离对象注册表Registry的实例,并点名端口为8888,这一步不可或缺(Java暗中同意端口是1099),不能缺少的一步,缺乏注册表成立,则不可能绑定对象到长途注册表上 
            LocateRegistry.createRegistry(8888); 

            //把远程对象注册到RMI注册服务器上,并取名叫ENCOREHello 
            //绑定的U科雷傲L标准格式为:rmi://host:port/name(在那之中契约名能够省略,下边二种写法都以不利的) 
            Naming.bind(“rmi://localhost:8888/RHello”,rhello); 
//            Naming.bind(“//localhost:8888/RHello”,rhello); 

            System.out.println(“>>>>>INFO:远程IHello对象绑定成功!”); 
        } catch (RemoteException e)

            System.out.println(“创造远程对象产生极其!”); 
            e.printStackTrace(); 
        } catch (AlreadyBoundException e) { 
            System.out.println(“产生再度绑定对象极其!”); 
            e.printStackTrace(); 
        } catch (MalformedURLException e) { 
            System.out.println(“产生UENVISIONL畸形万分!”); 
            e.printStackTrace(); 
        } 
    } 
}

 

/** 
* Created by IntelliJ IDEA. 
* User: leizhimin 
* Date: 2008-8-7 22:21:07 
* 客商端测验,在客商端调用长途对象上的长距离方法,并赶回结果。 
*/ 
public class HelloClient { 
    public static void main(String args[]){ 
        try { 
            //在RMI服务注册表中检索名字为陆风X8Hello的靶子,并调用其上的主意 
            IHello rhello =(IHello) Naming.lookup(“rmi://localhost:8888/RHello”); 
            System.out.println(rhello.helloWorld()); 
            System.out.println(rhello.sayHelloToSomeBody(“熔岩”)); 
        } catch (NotBoundException
e) { 
            e.printStackTrace(); 
        } catch (MalformedURLException e) { 
            e.printStackTrace(); 
        } catch (RemoteException e)

            e.printStackTrace();   
        } 
    } 
}

 

运作RMI服务端程序:

永利集团304com 1

 

运维RMI顾客端程序:

永利集团304com 2

 

总结:

从地点的经过来看,RMI对服务器的IP地址和端口注重很连贯,然而在支付的时候不知晓今后的服务器IP和端口怎么样,但是客商端程序注重那一个IP和端口。

那也是RMI的局限性之一。那几个主题素材有三种缓和门路:一是通过DNS来消除,二是经过包装将IP暴光到程序代码之外。

RMI的局限性之二是RMI是Java语言的中远距离调用,两端的程序语言必得是Java完成,对于分裂语言间的电视发表能够虚构用Web
Service或然公用对象须求代理系统(CORBA)来完毕。

 

 

 

 


RMI:远程方法调用(Remote Method
Invocation)。能够让在有些Java设想机上的靶子像调用本地对象同样调用另四个java
设想机中的对象上的主意。

永利集团304com 3

RMI远程调用步骤:

1,客商对象调用客商端协助对象上的格局

2,顾客端协助对象打包调用信息(变量,方法名),通过互联网发送给服务端帮助对象

3,服务端支持对象将客商端扶助对象发送来的消息解包,寻觅真正被调用的艺术以及该方法所在对象

4,调用真正服务指标上的真正方法,并将结果再次来到给服务端协助对象

5,服务端接济对象将结果打包,发送给客户端接济对象

6,顾客端扶助对象将再次回到值解包,再次回到给顾客对象

7,客商对象获得返回值

对于客商对象的话,步骤2-6是完全透明的

 

搭建一个RMI服务的历程分成以下7步;

1,创立远程方法接口,该接口必需继续自Remote接口

Remote
接口是三个标志接口,用于标志所包涵的点子能够从非本地虚构机上调用的接口,Remote接口自己不带有别的方式

[java] view
plain copy

 

  1. package server;  
  2.   
  3. import java.rmi.Remote;  
  4. import java.rmi.RemoteException;  
  5.   
  6. public interface Hello extends Remote {  
  7.     public String sayHello(String name) throws RemoteException;  
  8. }  

鉴于中远距离方法调用的本质如故是互联网通讯,只可是遮蔽了底层落成,网络通讯是断断续续会出现相当的,所以接口的具有办法都不可能不抛出RemoteException以证实该办法是有高风险的

2,创制远程方法接口达成类:

UnicastRemoteObject类的构造函数抛出了RemoteException,故其承袭类不能够运用暗中认可构造函数,承接类的构造函数必得也抛出RemoteException

由于措施参数与重回值最终都将要网络上传输,故必得是可类别化的

[java] view
plain copy

 

  1. package server;  
  2.   
  3. import java.rmi.RemoteException;  
  4. import java.rmi.server.UnicastRemoteObject;  
  5.   
  6. public class HelloImpl extends UnicastRemoteObject implements Hello {  
  7.     private static final long serialVersionUID = -271947229644133464L;  
  8.   
  9.     public HelloImpl() throws RemoteException{  
  10.         super();  
  11.     }  
  12.   
  13.     public String sayHello(String name) throws RemoteException {  
  14.         return “Hello,”+name;  
  15.     }  
  16. }  

3,利用java自带rmic工具生成sutb存根类(jdk1.5.0_15/bin/rmic)

jdk1.2自此的RMI能够通过反射API能够直接将呼吁发送给真实类,所以没有供给skeleton类了

sutb存根为远程方法类在地头的代办,是在服务端代码的基础上变化的,须要HelloImpl.class文件,由于HelloImpl承接了Hello接口,故Hello.class文件也是不可少的

Test

– – server

– – – – Hello.class

发表评论

电子邮件地址不会被公开。 必填项已用*标注