head first Design Pattern Proxy

客户对象-客户辅助对象-服务辅助对象-服务对象
RMI提供了客户辅助对象和服务辅助对象,自己不用写网路或IO代码,客户程序调用远程方法就和在运行本地JVM上对对象进行正常方法调用一样。RMI提过了查找服务用来寻找和访问远程对象。


制作远程服务:1. 制作远程接口:定义可以让客户远程调用的方法,客户将它用作服务的类类型。扩展java.rim.Remote 用远程接口扩展Remote这个接口
public interface MyRemote extends Remote{
//每次远程方法调用都必须考虑“有风险的”。在每个方法中声明RemoteException,可以让客户注意到这件事。
public String sayHello() throws RemoteException;
确定变量和返回值是属于原语(primitive)类型还是可序列化(Serializable)类型,因为远程方法的变量必须被打包并通过网络运送,要靠序列化来完成,如果使用原语类型、字符串和许多API中内定的类型(包括数组和集合)都不会有问题,但是对于自己定义的类,就必须保证你的类实现了Serializable。
}
2. 制作实际的工作类,实现远程接口
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote {
public String sayHello(){
return "fjkdjfk";
}
//超类UnicastRemoteObject构造器声明了异常,所以必须写一个构造器
public MyRemoteImpl() throws RemoteException{}
public static void main (String[] args){
try{
MyRemote service = new MyRemoteImpl();//产生远程对象
Naming.rebind("RemoteHello",service);//使用Naming.rebind()绑定到rmiregistry.客户将使用你所注册的名称在Rmi registry中寻找它。
}catch(Exception ex){
ex.printStackTrace();
}
}
}
3. 利用rmic产生stub和skeleton 3. 启动RMI registry(rmiregistry) 4. 开始远程服务,必须让服务对象开始运行,服务实现类实例化一个服务的实例,并将这个服务注册到RMI registry。
客户端:
public class MyRemoteClient{
public void static mian(String[] args){
new MyRemoteClient().go();
}
public void go(){
try{
MyRemote service = (MyRemote) Naming.lookup(rim://127.0.0.1/RemoteHello);
String s = service.sayHello();
System.out.println(s);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
代理模式:为另一个对象提供一个替身或占位符以控制这个对象的访问。
几种代理控制访问的方式:1. 代理控制访问远程对象。 2. 虚拟代理控制访问创建开销大的资源 3. 保护代理基于权限控制对资源的访问


Subject为RealSubject和Proxy提供接口,通过实现同一接口,Proxy在RealSubject出现的地方取代它,RealSubject是真正做事的对象,它是被Proxy代理和控制访问的对象。Proxy持有RealSubject的引用。某些情况下,Proxy还负责RealSubject对象的创建和销毁。客户和RealSubject的交互都必须通过Proxy。
虚拟代理作为创建开销大的对象的代表。通常直到我们真正需要一个对象的时候才创建它,当RealSubject对象在创建前和创建中时,由虚拟代理来扮演RealSubject对象的替身。RealSubject创建后,代理就会将请求直接委托给RealSubject对象。例如打开网络中的图片可以创建一个Icon接口从网络上加载图像,但下载需要很长时间,在等待加载图像的时候,应该显示一些东西,一旦图像加载完成,刚才显示的东西应该消失,图像显示出来。此时就可以用一个虚拟代理来代理Icon,管理背景的加载,并在加载未完成时显示“loading。。。”,一旦加载完成,代理就把显示的职责委托给Icon。
Java在java.lang.reflect包中有自己的代理支持,利用这个包,可以在运行时动态地创建一个代理类,实现一个或多个接口,并将方法的调用转发到你所指定的类。实际的代理类是在运行时创建,代码开始执行时还没有Proxy类,需要根据从你传入的接口集中创建。称为:动态代理。
Java会自动创建Proxy类,InvocationHandler响应代理的任何调用。


创建两个InvocationHandler,一个给拥有者使用,另一个给非拥有者使用,当代理被调用的时候,代理就会把这个调用转发给InvocationHandler,写代码创建动态代理,利用适当的代理包装任何PersonBean对象
保护代理:根据访问权限决定客户可否访问对象的代理。如有一个雇员对象,保护代理允许雇员调用对象上的某些方法,经理还可以多调用一些其他方法,而人力资源处的雇员可以调用对象上的所有方法。
Java5的RMI和动态代理搭配使用,动态代理产生stub,远程对象stub是java.lang.reflect.Proxy实例,它是自动产生的,来处理所有把客户的本地调用转变成远程调用的细节。不需要再使用rmic。
代理模式有很多变体:缓存代理,同步代理,防火墙代理和写入时复制代理

posted @ 2010-06-01 19:06  莫忆往西  阅读(170)  评论(0编辑  收藏  举报