远程方法调用(Remote Method Invocation,RMI)从JDK1.1就已经实现,它大大增强了Java开发分布式应用的能力。可以实现通过网络完成不同JVM间的通信,不仅可以传递基本的数据类型,对象也是可以传递的。RMI是JVM间的通信,如果服务器或客户端不是Java语言开发的,可以考虑web service或者corba。

RMI可以实现调用的透明性及安全性,客户端本身不关心功能是怎么实现的,只需要调用服务器端代码并关心结果即可。功能只限制于服务器端,客户端无法任意进行操作,也提供了安全性。

RMI利用JNDI在服务器端注册客户端需要调用的类。具体的调用是存根和骨架之间完成的,可以看做是客户端和服务器端的代理。

IHello定义了服务器和客户端间通信的接口,客户端只需要调用IHello中的方法即可。IHello需要集成Remote接口,所有方法需要抛出

RemoteException。

/** * 定义一个远程接口,必须继承Remote接口,其中需要远程调用的方法必须抛出RemoteException异常 */ public interface IHello extends Remote { public User user = new User(); public User getUser() throws RemoteException;; public void setUser(User user) throws RemoteException;; /** * 简单的返回“Hello World!"字样 * @return 返回“Hello World!"字样 * @throws java.rmi.RemoteException */ public String helloWorld() throws RemoteException; /** * 一个简单的业务方法,根据传入的人名返回相应的问候语 * @param someBodyName 人名 * @return 返回相应的问候语 * @throws java.rmi.RemoteException */ public String sayHelloToSomeBody() throws RemoteException; } 

HelloImpl是服务器端实际实现的方法,客户端通过RMI实际调用的就是HelloImpl。

/** * 远程的接口的实现 */ public class HelloImpl extends UnicastRemoteObject implements IHello { private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } private static final long serialVersionUID = -8403069777370518716L; /** * 因为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() throws RemoteException { return user.getName() + "!"; } } 

HelloServer完成的是注册功能,将上面实际工作的HelloImpl进行注册,客户端调用时查找已经注册的HelloImpl实例并调用即可。注册的地址是localhost的8888端口。不同的JVM时将localhost改为具体的IP即可。

/** * 创建RMI注册表,启动RMI服务,并将远程对象注册到RMI注册表中。 */ public class HelloServer { private static User user = new User(); public User getUser() { return user; } public void setUser(User user) { this.user = user; } public static void main(String args[]) { try { //创建一个远程对象 HelloImpl rhello = new HelloImpl(); //本地主机上的远程对象注册表Registry的实例,并指定端口为8888,这一步必不可少(Java默认端口是1099),必不可缺的一步,缺少注册表创建,则无法绑定对象到远程注册表上 LocateRegistry.createRegistry(8888); //把远程对象注册到RMI注册服务器上,并命名为RHello //绑定的URL标准格式为: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("发生URL畸形异常!"); e.printStackTrace(); } } } 

HelloClient模拟了客户端的调用,从localhost的8888端口找到注册的HelloImpl实例并调用。

/** * 客户端测试,在客户端调用远程对象上的远程方法,并返回结果。 */ public class HelloClient { public static void main(String args[]){ try { //在RMI服务注册表中查找名称为RHello的对象,并调用其上的方法 IHello rhello =(IHello) Naming.lookup("rmi://localhost:8888/RHello"); System.out.println(rhello.helloWorld()); User user = new User(); user.setName("inso"); rhello.setUser(user); System.out.println(rhello.sayHelloToSomeBody()); } catch (NotBoundException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (RemoteException e) { e.printStackTrace(); } } } 

User用于客户端调用服务器端代码时传递的参数,说明RMI支持传递对象,需要实现Serializable接口。

public class User implements Serializable{ private static final long serialVersionUID = -4631891643752276172L; private String name; public String getName() { return "user's name is " + name; } public void setName(String name) { this.name = name; } } 

先启动HelloServer注册实例,再启动HelloClient进行调用即可看到结果。

还可以将IHello.java,HelloClient.java,User.java拷贝到另外的机器上,模拟客户端实现真正的分布式测试。将服务器端和客户端的localhost改为具体的IP即可。

RMI基础的更多相关文章

  1. RMI基础篇

    远程方法调用(Remote Method Invocation,RMI)从JDK1.1就已经实现,它大大增强了Java开发分布式应用的能力. RMI可以实现通过网络完成不同JVM间的通信,不仅可以传递 ...

  2. Java RMI之HelloWorld篇

    Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可以用此方 ...

  3. JAVA RMI helloworld入门

    Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可以用此方 ...

  4. java的RMI(Remote Method Invocation)

    RMI 相关知识RMI全称是Remote Method Invocation-远程方法调用,Java RMI在JDK1.1中实现的,其威力就体现在它强大的开发分布式网络应用的能力上,是纯Java的网络 ...

  5. Java RMI 远程方法调用

    Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可以用此方 ...

  6. Java远程方法调用(RMI)

    Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可以用此方 ...

  7. Java RMI简单例子HelloWorld

    Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可以用此方 ...

  8. Java RMI 框架_远程方法调用(2016-08-16)

    概念: Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可 ...

  9. 【Socket】Java Socket基础编程

    Socket是Java网络编程的基础,了解还是有好处的, 这篇文章主要讲解Socket的基础编程.Socket用在哪呢,主要用在进程间,网络间通信.本篇比较长,特别做了个目录: 一.Socket通信基 ...

随机推荐

  1. 【Git】Git基础操作

    repository:版本库又名仓库,可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改.删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以&q ...

  2. linux 下CentOS 下 npm命令安装gitbook失败的问题

    运行环境 linux 服务器:CentOS 7.0 系统:安装了nodejs :使用 npm 安装 gitbook 出现错误提示: npm install -g gitbook-cli symbol ...

  3. .27-浅析webpack源码之事件流make(2)

    上一节跑到了NormalModuleFactory模块,调用了原型方法create后,依次触发了before-rsolve.factory.resolver事件流,这节从resolver事件流开始讲. ...

  4. .25-浅析webpack源码之事件流compilation(3)

    这一节跑下一批plugin. compiler.apply( new EnsureChunkConditionsPlugin(), new RemoveParentModulesPlugin(), n ...

  5. CSS background-clip 属性

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  6. protobuf 编码实现解析(java)

    一:protobuf编码基本数据类型 public enum FieldType { DOUBLE (JavaType.DOUBLE , WIRETYPE_FIXED64 ), FLOAT (Java ...

  7. es6重点笔记:let,const

    一,let 先看代码: var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i) }; } a ...

  8. aliyun 购买的linux安装tomcat

    按照网上的教程,下载tomcat,解压(即安装),启动,发现无法访问.有说端口未开放,修改/etc/sysconfig/iptables,添加端口开放.未发现有此文件,只有iptables-confg ...

  9. Servlet开篇

    Servlet开篇 前面我已经说过好多遍了,如何学习好一个东西其实就是2个问题: 1,这个东西是干嘛的?为什么要玩这个东西? 2,怎么样就玩好这个东西了?具体的应该玩这个东西的什么? 其实现在对于我来 ...

  10. linkin大话面向对象--多态

    java引用变量有2个类型,一个是编译时类型,一个是运行时类型: 编译时类型:声明的类型,把它看做是什么东西 运行时类型:真正的类型,实际上指的是什么东西 如果编译时类型和运行时类型不同,就出现多态. ...