(六)代理模式
代理模式(Proxy Pattern)指为其他对象提供一种代理,以控制这个对象的访问。当无法或者不想直接引用某个对象时,或者访问某个对象存在困难时,可以通过代理对象来访问。代理模式的两个主要目标:1,保护目标对象;2,增强目标对象。
1,代理模式的设计原则
1,抽象主题(ISubject):负责声明真实主题与代理类的共同接口方法;
2,真实主题(RealSubject):即被代理类;
3,代理主题(Proxy):即代理类,在内部持有真实主题的引用,因此具有代理权。

2,简单例子
代理有两种,静态代理和动态代理之分。我们先来举个静态代理的例子,比如父亲给儿子相亲。
public interface IPerson {
void findGirls();
}
public class Father implements IPerson {
// 对儿子的引用
private Son son;
public Father(Son son){
this.son = son;
}
@Override
public void findGirls() {
System.out.println("帮儿子相亲!");
son.findGirls();
System.out.println("相亲成功!");
}
}
public class Son implements IPerson {
@Override
public void findGirls() {
System.out.println("相亲!");
}
}
public class Client {
public static void main(String[] args) {
Father father = new Father(new Son());
father.findGirls();
}
}
也就是说,父亲只能帮儿子相亲,不能帮别人了(这就是静态代理的模式)。这对以后的发展肯定是不行的,我们需要让专业的人做专业的事情,比如媒婆(动态代理)。我们使用jdk自带的代理方式实现:
public class JDKMeipo implements InvocationHandler {
// 接口型的被代理对象的引用
private IPerson target;
public IPerson getInstance(IPerson target){
this.target = target;
Class<? extends IPerson> clazz = target.getClass();
return (IPerson) Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 业务处理
before();
Object result = method.invoke(this.target,args);
after();
return result;
}
public void before(){
System.out.println("媒婆安排相亲!");
}
public void after(){
System.out.println("成功!");
}
}
动态代理的实现及机制包括jdk本身的通过反射实现动态代理,还有就是CGLib库提供的动态代理方式。
//待补充
CGLib和JDK动态代理的对比分析:
1,jdk动态代理实现了被代理对象的接口,CGLib动态代理继承了被代理对象;
2,jdk动态代理和CGLib都是在运行期间生成字节码,jdk动态代理直接写Class字节码,CGLib使用ASM框架写字节码,CGLib更复杂,生成代理类效率低。
3,jdk通过反射机制实现动态代理,CGLib通过FastClass机制直接调用,执行效率高。
3,代理模式的点评
代理模式能将代理对象与真实被调用目标对象分离,解耦,扩展性好;可以实现保护目标和增强目标对象的作用。不足是导致实现复杂,在目标对象中增加代理可能会导致处理请求变慢。