Java代理模式(Proxy)

一、作用:
      为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。使用代理模式创建代理对象,让代理对象控制目标对象的访问(目标对象可以是远程的对象、创建开销大的对象或需要安全控制的对象),并且可以在不改变目标对象的情况下添加一些额外的功能。

二、结构图


三、在代理模式中的角色:
  
1)抽象对象角色(Subject):抽象主题角色,抽象主题类可以是抽象类,也可以是接口,是一个最普通的业务类型定义,声明了目标对象和代理对象的共同接口,这样一来在任何可以使用目标对象的地方都可以使用代理对象。
  2)目标对象角色(RealSubject):具体主题角色,也叫被委托角色、被代理角色。定义了代理对象所代表的目标对象,是业务逻辑的具体执行者。
  3)代理对象角色(Proxy):代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象提供一个与目标对象相同的接口,以便可以在任何时候替代目标对象,它把所有抽象主题类定义的方法给具体主题角色实现。代理对象通常在客户端调用传递给目标对象之前或之后,执行某个操作,而不是单纯地将调用传递给目标对象。

四、示例程序:

Subject类:

public interface Subject {
	public void operate();
}
RealSubject 类:

public class RealSubject implements Subject {

	@Override
	public void operate() {
		System.out.println("realSubject operatestarted......");
	}
}
Proxy类:

public class Proxy implements Subject {
	private Subject subject;

	public Proxy(Subject subject) {
		this.subject = subject;
	}

	@Override
	public void operate() {
		System.out.println("before operate, proxy......");
		subject.operate();
		System.out.println("after operate, proxy......");
	}
}
Client:

public class Client {

	public static void main(String[] args) {
        Subject subject = new RealSubject();
        Proxy proxy = new Proxy(subject);
        proxy.operate();
	}
}
运行结果:

before operate, proxy......
realSubject operatestarted......
after operate, proxy......
五、Java中动态代理
      Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:
      (1).Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,这个抽象方法在代理类中动态实现。
     (2).Proxy:该类即为动态代理类,其中主要包含以下内容:Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。
    Static Class getProxyClass (ClassLoader loader, Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。
     Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。
     所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。在使用动态代理类时,我们必须实现InvocationHandler接口,
六、静态代理和动态代理
      采用Java代理模式,代理类通过调用委托类对象的方法,来提供特定的服务。委托类需要实现一个业务接口,代理类返回委托类的实例接口对象。按照代理类的创建时期,可以分为:静态代理和动态代理。
      所谓静态代理:指程序员创建好代理类,编译时直接生成代理类的字节码文件;所谓动态代理:在程序运行时,通过反射机制动态生成代理类。
     静态代理类的特点:代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法。这样就出现了大量的代码重复。而且代理类只能为特定的接口(Service)服务;动态代理:代理类需要实现InvocationHandler接口。
七、代理模式的应用场景: 
(1)远程代理(Remote Proxy):典型的就是客户端与webservice使用的情况,客户端由于是针对OOP编程,而不是针对webservice中的方法进行编程,所以得在客户端模拟一下webservice的环境,用proxy来对webservice进行包装,这样就可以使用proxy代理类来远程操作webservice了;
(2)虚拟代理(Virtual Proxy):比如你要开发一个大文档查看软件,大文档中有大的图片,有可能一个图片有100MB,在打开文件时不可能将所有的图片都显示出来,这样就可以使用代理模式,当需要查看图片时,用proxy来进行大图片的打开;
(3)防火墙代理(Firewall Proxy):控制网络资源的访问,保护主题免于恶意客户的侵害;
(4)保护代理(Protection (Access)Proxy):为不同的客户提供不同级别的目标对象访问权限;
(5)智缓存代理(Cache Proxy):为开销大的运算结果提供暂时存储,它允许多个客户共享结果,以减少计算或网络延迟;
(6)同步代理(SynchronizationProxy):在多线程的情况下为主题提供安全的访问;
(7)写入时复制代理(Copy-On-Write Proxy):用来控制对象的复制,方法是延迟对象的复制,直到客户真的需要为止,是虚拟代理的一个变体;
(8)智能引用代理(Smart ReferenceProxy):当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等;
(9)复杂隐藏代理(Complexity HidingProxy):用来隐藏一个类的复杂集合的复杂度,并进行访问控制。有时候也称为外观代理(Façade Proxy),但是复杂隐藏代理和外观模式是不一样的,因为代理控制访问,而外观模式只提供另一组接口。

现实中,Proxy应用范围很广,现在流行的分布计算方式RMI和Corba等都是Proxy模式的应用



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值