认识RMI和代理模式

作为工作3年多的我,发现在自己在代码的设计缺乏良好的思路有,所以想学习系统的设计模式,最近看了接口模式、适配器、外观、组合、代理模式,

说实话组合模式看着比较迷惑,后续还要看几遍多理解下,刚好在看代理模式,写个小例子,并学习下RMI(远程方法调用)

1、代码文件结构如下:

2、Rocket.java 远程接口,必须继承Remote的接口,Remote接口并不包含任何方法,只用于标识其方法可以从非本地虚拟机上调用的接口。
任何远程对象都必须直接或间接实现此接口。只有在“远程接口”(扩展 java.rmi.Remote 的接口)中指定的这些方法才可远程使用。

接口中方法都需要throws RemoteException,RemoteException 是许多与通信相关的异常的通用超类,这些异常可能会在执行远程方法调用期间发生。

远程接口(扩展 java.rmi.Remote 的接口)的每个方法必须在其 throws 子句中列出 RemoteException。 

package com.jaws.proxy;


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


/**
 * 远程接口,必须继承Remote接口
 * @author jiangpan
 *
 */
public interface Rocket extends Remote{
public void start() throws RemoteException;

}

3、RocketImpl.java,远程对象,实现Rocket接口;必须继承UnicastRemoteObject类,UnicastRemoteObject用于导出带 JRMP 的远程对象和获得与该远程对象通信的 stub。我并知道JRMP是什么,就百度了下JRMP,以下是百科中对JRMP的解释:

JRMP:java remote method protocol,Java远程方法协议
JRMP是的Java 技术协议的具体对象为希望和远程引用。JRMP只能是一个Java特有的,基于流的协议。相对于的RMI - IIOP的 ,该协议JRMP只能是一个对象的Java到Java的远程调用,这使得它依赖语言,意思是客户端和服务器必须使用Java。
JRMP:Java远程消息交换协议JRMP(Java Remote Messaging Protocol)

package com.jaws.proxy;


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


/**
 * 远程对象,必须继承UnicastRemoteObject
 * @author jiangpan
 *
 */
public class RocketImpl extends UnicastRemoteObject implements Rocket{


public RocketImpl() throws RemoteException {
super();
// TODO Auto-generated constructor stub
}


@Override
public void start() throws RemoteException {
// TODO Auto-generated method stub
System.out.println("server: rocket starting....");
}
}

4、通过JDK中的RMIC.exe工具编译RocketImpl.class



通过RMIC编译后,将在同级目录RocketImpl_Stub.class,这个类就是工具为RocketImpl(远程对象)自动生成的代理类(stub),stub是用于返回给客户端的代理对象,客户端通过stub对象调用远程对象的方法,stub对象隐藏网络传输的过程,使我们只需要写简单的代码就能调用远程对象的方法。


5、启动rmiregistry服务,有两种方式启动

  a.通过命令方式启动

  b.通过代码方式启动 LocateRegistry.createRegistry(5000);//如果是在实际开发中,我觉得通过代码的方式启动比命令启动好


6、RegisterRocket .java,创建远程对象,并注册到对象注册表中

package com.jaws.proxy;


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


/**
 * 创建远程对象,并注册
 * @author Administrator
 *
 */
public class RegisterRocket {
public static void main(String[] args) {
try {
//通过代码的方式启动RMIRegistry服务
LocateRegistry.createRegistry(5000);
RocketImpl biggie = new RocketImpl();

//对象与HTTP地址绑定,格式为rmi://host:port/name,

Naming.rebind("rmi://localhost:5000/Biggie", biggie);// 将指定名称重新绑定到一个新的远程对象
System.out.println("registered biggie");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}

}
}

启动完成,程序一直在运行状态

7、ShowRocketClient .java,模拟客户端调用的远程方法

package com.jaws.proxy;


import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;


import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;


public class ShowRocketClient {
public static void main(String[] args) {
try {

Context context = new InitialContext();
//通过JDNI获取远程对象
Object stub1 = context.lookup("rmi://localhost:5000/Biggie");
//通过RMI获取远程的代理对象
Object stub2 = Naming.lookup("rmi://localhost:5000/Biggie");//返回与指定 name 关联的远程对象的引用(一个 stub)
Rocket rocket1 = (Rocket)stub1;
rocket1.start();
Rocket rocket2 = (Rocket)stub2;
rocket2.start();

} 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();
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

运行客户端程序后,远程端打印日志,证明的远程对象的start()被执行



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值