Java远程方法调用(RMI)

本文概述

  • 了解分布式应用程序的需求
  • Java长的最低安置补助
  • RMI的例子
【Java远程方法调用(RMI)】RMI(远程方法调用)是一个API,它提供了一个机制来在java创建分布式应用程序。RMI允许一个对象调用一个对象的方法在另一个JVM中运行。
RMI远程应用程序使用两个对象之间的通信提供了存根和骨架。
理解存根和骨架
RMI使用存根和骨架对象与远程对象进行通信。
一个远程对象调用一个对象的方法可以从另一个JVM。让我们理解存根和骨架对象:
存根
存根是一个对象,充当客户端网关。所有即将离任的请求路由。它驻留在客户端和远程对象。当调用者调用存根对象上的方法,它下面的任务:
  1. 它启动一个连接与远程虚拟机(JVM),
  2. 它写道,(警察)的参数传递到远程虚拟机(JVM),
  3. 它等待结果
  4. 它读取(解封)返回值或异常
  5. 最后,返回给调用者的值。
骨架
骨架是一个对象,作为网关服务器端对象。所有传入的请求路由。当骨架接收传入的请求时,它确实以下任务:
  1. 它读取参数的远程方法
  2. 它在实际的远程对象调用方法,和
  3. 它写道,(警察)结果传送给调用者。
了解分布式应用程序的需求如果任何应用程序执行这些任务,分布式应用程序。
  1. 应用程序需要定位远程方法
  2. 它需要提供与远程对象通信,和
  3. 应用程序需要加载的类定义对象。
RMI应用所有这些特性,所以它被称为分布式应用程序。
Java长的最低安置补助是考虑到6的步骤编写RMI程序。
  1. 创建远程接口
  2. 提供远程接口的实现
  3. 编译实现类并创建存根和骨架对象使用rmic工具
  4. 通过rmiregistry启动注册表服务工具
  5. 创建和启动远程应用程序
  6. 创建并启动客户机应用程序
RMI的例子在这个例子中,我们是所有6的步骤来创建和运行rmi应用程序。客户端应用程序只需要两个文件,远程接口和客户端应用程序。在rmi应用程序中,客户机和服务器与远程接口进行交互。客户端应用程序调用代理对象上的方法,RMI远程JVM发送请求。返回值被发送回代理对象,然后客户端应用程序。
1)创建远程接口
创建远程接口,扩展远程接口和声明RemoteException远程接口的所有方法。在这里,我们创建一个远程接口,扩展了远程接口。只有一个方法add(),它声明RemoteException。
import java.rmi.*; public interface Adder extends Remote{ public int add(int x,int y)throws RemoteException; }

2)提供远程接口的实现
现在提供远程接口的实现。提供远程接口的实现,我们需要
  • 扩展UnicastRemoteObject类,
  • 或使用exportObject UnicastRemoteObject()方法的类
import java.rmi.*; import java.rmi.server.*; public class AdderRemote extends UnicastRemoteObject implements Adder{ AdderRemote()throws RemoteException{ super(); } public int add(int x,int y){return x+y; } }

3)使用rmic创建存根和骨架对象工具。
下一步是创建存根和骨架对象使用rmi编译器。rmic工具调用RMI编译器并创建存根和骨架对象。
rmic AdderRemote

4)rmiregistry启动注册表服务的工具
现在开始注册表服务通过使用rmiregistry工具。如果你不指定的端口号,它使用一个默认的端口号。在这个例子中,我们使用的端口号5000。
rmiregistry 5000

5)创建和运行服务器应用程序
现在rmi服务需要驻留在服务器进程。命名类提供了方法来获取和存储远程对象。命名类提供了5个方法。
public static java.rmi.Remote lookup(java.lang.String) throws java.rmi.NotBoundException,java.net.MalformedURLException,java.rmi.RemoteException; 它返回远程对象的引用。
公共静态空间绑定(. lang。字符串,抛出java.rmi java.rmi.Remote)。AlreadyBoundException、java.net.MalformedURLException java.rmi.RemoteException; 它将远程对象与给定名称绑定。
public static void unbind(java.lang.String) throws java.rmi.RemoteException,java.rmi.NotBoundException,java.net.MalformedURLException; 它破坏了远程对象绑定的名字。
public static void rebind(java.lang.String,java.rmi.Remote) throws java.rmi.RemoteException,java.net.MalformedURLException; 它将远程对象绑定到新名称。
公共静态. lang。String[]列表(以)抛出java.rmi。java.net.MalformedURLException RemoteException异常; 它返回在注册表中绑定的远程对象的名称的数组。
在这个例子中,我们具有约束力sonoo远程对象的名称。
import java.rmi.*; import java.rmi.registry.*; public class MyServer{ public static void main(String args[]){ try{ Adder stub=new AdderRemote(); Naming.rebind("rmi://localhost:5000/sonoo",stub); }catch(Exception e){System.out.println(e); } } }

6)创建并运行客户端应用程序
在客户端我们查找的存根对象命名类的()方法和调用这个对象的方法。在这个例子中,我们服务器和客户端应用程序,运行在同一台机器我们使用localhost。如果你想从另一台机器上访问远程对象,改变本地主机的主机名(或IP地址)远程对象的位置。
import java.rmi.*; public class MyClient{ public static void main(String args[]){ try{ Adder stub=(Adder)Naming.lookup("rmi://localhost:5000/sonoo"); System.out.println(stub.add(34,4)); }catch(Exception e){} } }

For running this rmi example,1) compile all the java filesjavac *.java2)create stub and skeleton object by rmic toolrmic AdderRemote3)start rmi registry in one command promptrmiregistry 50004)start the server in another command promptjava MyServer5)start the client application in another command promptjava MyClient

这个RMI示例的输出
有意义的RMI应用程序与数据库的例子
考虑这样一个场景,有两个在不同的机器上运行的应用程序。,中假设是MachineA和MachineB是MachineA位于美国和印度MachineB。MachineB想是MachineA应用程序的所有客户的列表。
让我们开发RMI应用程序遵循的步骤。
1)创建的表首先,我们需要在数据库中创建表。在这里,我们使用Oracle10数据库。
2)创建Customer类和远程接口
package com.srcmini; public class Customer implements java.io.Serializable{ private int acc_no; private String firstname,lastname,email; private float amount; //getters and setters }

注意:客户类必须是可序列化的。
package com.srcmini; import java.rmi.*; import java.util.*; interface Bank extends Remote{ public List< Customer> getCustomers()throws RemoteException; }

3)创建类,提供远程接口的实现
package com.srcmini; import java.rmi.*; import java.rmi.server.*; import java.sql.*; import java.util.*; class BankImpl extends UnicastRemoteObject implements Bank{ BankImpl()throws RemoteException{}public List< Customer> getCustomers(){ List< Customer> list=new ArrayList< Customer>(); try{ Class.forName("oracle.jdbc.driver.OracleDriver"); Connection con=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","system","oracle"); PreparedStatement ps=con.prepareStatement("select * from customer400"); ResultSet rs=ps.executeQuery(); while(rs.next()){ Customer c=new Customer(); c.setAcc_no(rs.getInt(1)); c.setFirstname(rs.getString(2)); c.setLastname(rs.getString(3)); c.setEmail(rs.getString(4)); c.setAmount(rs.getFloat(5)); list.add(c); }con.close(); }catch(Exception e){System.out.println(e); } return list; }//end of getCustomers() }

4)编译类rmic工具,通过rmiregistry启动注册表服务工具5)创建和运行服务器
package com.srcmini; import java.rmi.*; public class MyServer{ public static void main(String args[])throws Exception{ Remote r=new BankImpl(); Naming.rebind("rmi://localhost:6666/srcmini",r); }}

6)创建和运行客户端
package com.srcmini; import java.util.*; import java.rmi.*; public class MyClient{ public static void main(String args[])throws Exception{ Bank b=(Bank)Naming.lookup("rmi://localhost:6666/srcmini"); List< Customer> list=b.getCustomers(); for(Customer c:list){ System.out.println(c.getAcc_no()+" "+c.getFirstname()+" "+c.getLastname() +" "+c.getEmail()+" "+c.getAmount()); }}}

    推荐阅读