代理(Proxy)

98 阅读2分钟

代理:帮房东“租房子”的中介。

但代理一般会有一些“附属操作”(看房、签合同、收中介费)!

步骤:

  1. 接口(抽象角色)
  2. 真实角色(房东)
  3. 代理角色(中介)
  4. 客户 访问 代理角色

好处:

  • 可以使 真实角色(房东) 的操作更加纯粹,不用去关注一些公共业务
  • 公共业务也就交给 代理角色(中介),实现了业务的分工!
  • 公共业务发生拓展时,方便集中管理

缺点:

  • 一个真实角色(房东)就会产生一个代理角色(中介)

动态代理:动态生成“中介”

  • 动态代理和静态代理角色一样

  • 动态代理的代理类动态生成,不是我们自己写好的

  • 动态代理分为两大类:(1)基于接口的动态代理;(2)基于类的动态代理

    • 基于接口——JDK 动态代理
    • 基于类:cglib
    • Java字节码 JAVAsist
  • Proxy(代理)

    • Class,reflect
    • 提供了创建 动态代理类 和 实例 的 静态方法
  • InvocationHandler(接口,reflect包):调用处理程序

    • 是由 代理实例调用处理程序 实现的接口。每个 代理实例 都有一个关联的调用处理程序。
    • 只有一个invoke
//ProxyInvocationHandler.java
public class ProxyInvocationHandler implements InvocationHandler {
    //被代理的接口
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    //生成代理对象
    public Object getProxy() {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                this);
    }

    //处理代理实例,并返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        log(method.getName());
        
        //method.invoke()的返回值将是被调用方法的返回值
        Object result = method.invoke(target, args);
        return result;
    }

    public void log(String msg) {
        System.out.println(msg);
    }
}

一个动态代理类代理的是一个接口,一般就是一个业务;

一个动态代理类可以代理多个类,只要是实现的是同一个接口即可!

  • 适配器重点在于:衔接不同类型的类或接口;代理的重点在于:处理不同类之间的逻辑实现
  • 适配器不是完成工作的主体,完成工作的主体是适配的对象;代理是要完成主要工作。