Java 动态代理

动态代理

利用 Java 的反射技术 (Java Reflection), 在运行时创建一个实现某些给定接口的新类 (也称 “动态代理类”) 及其实例 (对象), 代理的是接口 (Interfaces), 不是类 (Class), 也不是抽象类. 在运行时才知道具体的实现, spring aop 就是此原理.

Object newProxyInstance(
    ClassLoader loader, # 用哪个类加载器去加载代理对象
    Class < ?>[]interfaces, # 动态代理类需要实现的接口
    InvocationHandler h # 执行时会调用 h 里面的 invoke 方法去执行
)throws IllegalArgumentException;

定义一个接口

public interface IVehical {
    void run();
}

扩展一个类

public class Car implements IVehical {
    @Override
    public void run() {
        System.out.println("Car 会跑");
    }
}

实现处理类

public class VehicalInvacationHandler implements InvocationHandler {
    private IVehical vehical;

    public VehicalInvacationHandler(IVehical vehical) {
        this.vehical = vehical;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("---------before-------");
        Object invoke = method.invoke(vehical, args);
        System.out.println("---------after-------");
        return invoke;
    }
}

invoke 有三个参数:

  • proxy 代理对象, 就是 newProxyInstance 返回的对象
  • method 调用的方法
  • args 方法中的参数
public static void main(String[] args) {
    IVehical car = new Car();
    car.run();
    System.out.println("============");
    ClassLoader classLoader = car.getClass().getClassLoader();
    Class<?>[] interfaces = car.getClass().getInterfaces();
    VehicalInvacationHandler h = new VehicalInvacationHandler(car);
    IVehical vehical = (IVehical) Proxy.newProxyInstance(classLoader, interfaces, h);
    vehical.run();
}

上面的代码, 代理 car 对象, 调用 run 方法时, 自动执行 InvocationHandler 中的 invoke 方法, 输出结果如下

Car 会跑
============
---------before-------
Car 会跑
---------after-------

参考资料