代理模式

Posted lovebolin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代理模式相关的知识,希望对你有一定的参考价值。

定义:为其他对象提供一种代理以控制对这个对象的访问。代理模式本质上也叫做委托模式,它是一种基本设计技巧,许多其他模式,比如状态模式,策略模式,访问者模式本质上是在特殊场合采用了委托模式。代理模式应用非常广泛,下面举出一个通用示例,假设现有三个角色,抽象主题、具体实现主题、代理主题:

//抽象主题类
public interface Subject{
    public void request();
}
//真实主题类
public class RealSubject implements Subject{
    //实现方法
    public void request(){
    }
}
//代理类
public class Proxy implements Subject{
    //要代理实现哪个类
    private Subject subject = null;
    //默认代理者
    public Proxy(){
        this.subject = new Proxy();
    }
    //通过构造函数传递代理类    
    public Proxy(Object... objects){
        
    }
    //实现接口中定义的方法
    public void request(){
        this.before();
        this.subject.request();
        this.after();
    }
    //预处理
    private void before(){
    }
    //后处理
    private void after(){
    }
}

代理模式有如下优点:

  • 职责清晰。真实的角色就是实现实际的业务逻辑,不用关心其他非本职的事务。
  • 高扩展性。具体主题角色是随时都会发生变化的,但只要他实现了接口,不管如何变化,都不会影响到代理类的使用
  • 智能化。比如动态代理

代理模式扩展:

  上述通用代码是普通代理,还可以改造为强制代理模式,也就是不允许直接new具体对象,必须通过代理产生;还有一种是个性化代理,一个类可以实现多个接口,完成不同任务的整合,代理的目的是在目标对象方法的基础上进行增强,这种增强本质上通常是拦截和过滤目标方法,只需要在普通代理类上实现更多接口即可实现;最后但很重要的一种就是动态代理,什么是动态代理?就是在实现阶段不用关心代理谁,只在运行阶段才指定代理哪个对象。相对而言,自己写代理类就是静态代理。现在非常常见的面向横切面编程,也就是AOP,其核心就是动态代理机制。

  提到动态代理,必须说下jdk提供的一个动态代理接口:InvocationHandler,通过这个接口,所有的方法都由该handler来处理,由它接管所有实际的处理任务。下面看一个动态代理通用编程模型,

  先看Subject接口,抽象主题类:

public interface Subject{
    //业务操作
    public void doSomething(String str);
}

  实现主题类:

//真实主题类
public class RealSubject implements Subject{
    //业务操作
    public void doSomething(String str){
    }
}

  重点的动态代理类:

//动态代理的Handler类
public
class MyInvocationHandler implements InvocationHandler{ //被代理的对象 private Object target = null; //传递一个对象 public MyInvocationHandler(Object _obj){ this.target = _obj; } //代理方法 public Object invoke(Object proxy, Method method, Object[] args) throws Throwble{   return method.invoke(this.target, args); } }

  所有通过动态代理实现的全部通过invoke()方法调用。动态代理:

public class DynamicProxy<T>{
    public static <T> T newProxyInstance(ClassLoader loader,Class<?> interfaces,  InvocationHandler h){
    //寻找JoinPoint连接点,AOP框架使用元数据定义
    if(true){
        //执行一个前置通知
        (new BeforeAdvice()).exec();
    }
    return (T)Proxy.newProxyInstance(loader, interfaces, h);
}
public interface IAdvice{
    public void exec();
}
public class BeforeAdvice implements IAdvice{
    public void exec(){
    }
}
//场景调用
public class Client{
    public static void main(String[] args){
        Subject subject = new RealSubject();
        //定义一个handler
        InvocationHandler hander = new MyInvocationHandle(subject);
        //定义主题的代理
        Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(),subject.getClass(),handler);
        proxy.doSomething("ok");
}

  在DynamicProxy类中,有这样的方法,

    Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(),subject.getClass(),handler); 
 该方法重新生成了一个对象,因为要使用代理!注意getInterfaces()这句话,查找所有该类的接口,然后实现接口中所有方法,当然,都是空方法,由谁来具体实现呢?
就是MyInvocationHandle这个对象。于是我们知道了,由
InvocationHandler实现接口中所有方法,由其invoke具体接管所有方法的实现。

 




以上是关于代理模式的主要内容,如果未能解决你的问题,请参考以下文章

scrapy按顺序启动多个爬虫代码片段(python3)

用于从 cloudkit 检索单列的代码模式/片段

java代码实现设计模式之代理模式

代理模式(静态代理动态代理)代码实战(详细)

Java设计模式-代理模式之动态代理(附源代码分析)

代理模式(静态代理)