代理模式是对象的结构模式,给一个对象提供一个代理对象,由代理对象控制对原对象的引用。我们可以通过操作代理对象实现对原对象的调用。
本文主要讲述静态代理,jdk动态代理,cglib动态代理三种。
- 远程(Remote)代理:
为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的空间地址可以是在本机器中,也可以是在另一台机器中。
- 虚拟代理:
根据需要创建一个资源消耗较大的对象,使得此对象在真正需要时才会被创建。
- Copy-on-Write 代理:
虚拟代理的一种,把复制拖延到只有在客户端需要时,才真正采取行动。
- 保护代理:
控制对一个对象的访问,如果需要,可以给不同的用户踢动不同级别的使用权限。
- Cache代理:
为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
- 防火墙代理:
保护目标,不让恶意用户接近。
- 同步化代理:
使几个用户能否同时使用一个对象而没有给冲突。
- 智能引用代理:
当一个对象被引用时,提供一些额外的操作,比如讲对象的调用次数记录下来。
代理模式所涉及的角色有:
- 抽象主题角色
- 真实主题角色
- 代理主题角色
1. 抽象主题角色
声明了真实主题和代理主题之间的共同接口,代理主题拥有和抽象主题一样的方法、属性,这样一来在任何可以只用真实主题的地方都可以只用代理主题。
/**
* 抽象主题
* @author wuqiong
*
*/
public abstract class Subject {
public abstract void request();
}
2. 真实主题角色
定义了真实对象,也就是我们想让代理对象操作的实际对象,它实现了抽象接口。
/**
* 真实主题
* @author wuqiong
*
*/
public class RealSubject extends Subject {
@Override
public void request() {
System.out.println("真实主题request方法执行");
}
}
3. 代理主题角色
代理主题角色同样实现抽象类,同时内部包含了对真实主题的引用,从而可以在任何时候操作真实主题对象。代理角色通常在客户端真正调用的真实主题之前或者之后,执行某个操作,而不是单独的将调用传递给真实的角色。
/**
* 代理主题角色
* @author wuqiong
*
*/
public class ProxySubject extends Subject {
private RealSubject realSubject = new RealSubject();
@Override
public void request() {
preRequest();
realSubject.request();
afterRequest();
}
public void preRequest() {
System.out.println("request方法执行之前执行");
}
public void afterRequest() {
System.out.println("request方法执行之后执行");
}
}
测试执行结果:
public class ProxyTest {
public static void main(String[] args) {
ProxySubject ps = new ProxySubject();
ps.request();
}
}
打印结果
request方法执行之前执行
真实主题request方法执行
request方法执行之后执行
从上面的代理主题类的代码可以看出代理模式是怎么样工作的,首先,代理模式并不改变主题的接口,因为模式的用意并不是让客户端感受到代理的存在。其次,代理使用委派将客户端的调用委派给真实的主题对象,代理主题在其中起到了传递请求的左右。最后,代理主题在传递请求之前和之后都可以执行特定的代码,而不是单纯的执行请求。
当客户端向代理主题发出请求时,代理主题接受到请求的同事,先执行一个preRequest()操作,然后才把请求传递给真实的主题。真实主题执行之后,又执行了afterRequest()方法,才将控制返回给客户端。
简而言之,就是代理模式将一个中间层插入到了客户端和主题角色之间,从而提供了许多灵活性。
动态代理见:JAVA设计模式之【代理模式】一(jdk动态代理)http://blog.csdn.net/emma_joans/article/details/78594185