动态代理特点

  • 作用与静态代理相同,都是起代理角色的作用。
  • 动态代理的代理类是动态生成的,不是我们事先写好的。
  • 动态代理分为两大类:基于接口的动态代理和基于类的动态代理。

    • 基于接口:JDK动态代理
    • 基于类:cglib
    • Java字节码实现:JAVAssist

基于接口的动态代理

本文主要讲解基于接口的动态代理。

相关类:Proxy,invocationHandler。

invocationHandler

以经典的中介代理房东租房的场景为例:

//租房接口
public interface Rent {
    public void rent();
}
//实现了租房接口的房东类
public class Host implements Rent {
    @Override
    public void rent() {
        System.out.println("房东要出租房子!");
    }
}

以代码为例展示基于接口的动态代理

//此类将自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {

  //被代理的接口
  private Rent rent;

  public void setRent(Rent rent) {
    this.rent = rent;
  }

  //生成得到代理类
  public Object getProxy() {
    return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);
  }

  //处理代理实例,并返回结果
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    //动态代理的本质就是使用反射实现,通过动态代理实现了执行方法前的seeHouse()操作
    seeHouse();
    Object result = method.invoke(rent, args);

    return result;

  }

  public void seeHouse() {
    System.out.println("中介看房子");
  }

}

测试:

public class Client {
  public static void main(String[] args) {
    //真实角色
    Host host = new Host();

    //代理角色
    ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();
    proxyInvocationHandler.setRent(host);


    Rent proxy = (Rent)proxyInvocationHandler.getProxy();

    proxy.rent();
  }
}

小结

InvocationHandler与Proxy的作用

  • InvocationHandler作用:由代理实例(xxxProxy)调用处理程序实现的接口。
  • Proxy作用:提供了创建 动态代理类和实例静态方法

动态代理的优点

  1. 拥有静态代理具有的优点:

    • 可以使真实角色的操作更加纯粹,不必去关注一些公共的业务。
    • 公共业务也就交给代理角色,实现了业务的分工。
    • 公共业务发生扩展的时候,方便集中管理。
  2. 相对于静态代理的优点:

    动态代理不需要自己编写代理类,其是动态生成的。这样最明显的好处是:如果目标对象的接口有很多方法的话,我们编写静态代理类需要将接口的方法一一实现 (假设Rent接口中还有一个demo()方法,就需要自己在静态代理类中也手动实现demo()方法),在接口和方法繁多的工程中,这带来的维护成本是极高的)。

    若是使用动态代理,代理对象的生成是利用JDKAPI,动态地在内存中构建代理对象(需要我们指定创建 代理对象/目标对象 实现的接口的类型),并且会默认实现接口的全部方法,这就没有了静态代理的上述缺点。

最后修改:2020 年 11 月 03 日 10 : 56 AM