代理模式: 为另一个对象提供一个替身或者占位符以控制对这个对象的访问。
使用代理模式创建代表,让代表对象控制某对象的访问,被代理的对象可以是远程的对象、创建开销大的对象或需要安全控制的对象。
RMI 全称Remote Method Invocation,远程方法调用 ,rmiregistry含义:远程方法调用注册。
RMI提供了客户辅助对象和服务辅助对象,给客户辅助对象创建的方法和服务对象的方法相同。
RMI好处是不需要自己写网络或I/O代码。客户端调用远程方法如同在本地JVM调用自己的方法一样。 并提供所有运行时的基础设施,包括如使用Naming找到服务lookup service、rebind、bind服务,这个服务用来寻找和访问远程对象。
下图是RMI的结构图:
注意:stub表示桩 ,skeleton表示骨架,新版的java不需要显示的skeleton.
方法调用的过程:远程服务接口定义的方法是:doSomething(),
客户端是如何获取到stub对象?
客户端从Registry远程服务注册表找到Naming.lookup(“rmi://地址/远程绑定的服务名”)获取该服务名的代理客户辅助对象 stub,然后可以通过代理对象调用远程服务的方法。
制作远程服务的步骤:
步骤一: 制作服务端的远程接口 ,MyRemote.java
步骤二: 实现服务端的远程接口 , MyRemoteImpl.java
实现的过程需要注意以下:
1. 类应该继承UnicastRemoteObject,使之成为远程服务对象
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote
2. 默认构造器需要抛出 RemoteException异常 因为父类构造会抛,子类构造也要抛
3. 在实现接口方法时,如果涉及到的数据类型不是 primitive或可序列化Serializable的,需要在自定义的数据类型类实现Iimplements Serializable 接口
因为基本上是用于网络I/O等,必须可序列化传输。
步骤三: 利用rmic产生stub和skeleton (java新版不需要此操作,可以跳过,猜测应该内置可生成),执行:rmic MyRemoteImpl.java
这就是结构图上的客户和服务辅助类,是由工具产生的。生成: MyRemoteImpl_Stub.class MyRemoteImpl_Skel.class
步骤四: 启动 RMI registry服务
打开终端执行 :rmiregistry命令;即在服务端启动RMI服务,用来下一步的注册。
步骤五: 开启远程服务
这个开启肯定是在main(),至于这个main()的类,可以是在远程服务实现类,也可以是自定义的另一个类。
在main()方法中,我们可以用RMI Registry注册实现的远程服务 MyRemoteImpl。
// 用RMI Registry注册远程实现接口的服务,这样客户端就可以通过名称查询注册表获取客户端辅助对象stub,并可以调用远程服务的方法
tr