Java使用Porxy和InvocationHandler实现动态代理

静态代理

先看看手动实现静态代理

静态代理的两个要点:

  • 1,代理类和委托列要实现相同的接口

  • 2,代理类中,要持有委托类的对象


缺点:每一个静态代理类都需要手工创建,比较繁琐

动态代理:

  • 动态代理类会根据接口的结构,自动在运行时内存生成,其核心原理是Java反射

创建一个实现了InvokationHandler接口的类。

  • .首先创建具有相同扩展功能的”代理类“,在动态生成真正的代理类时要传入这个扩展功能的类,来实现对接口的增强。
public class ProxyInvocationHandler implements  InvocationHandler {

    private Object targetObject;//目标对象

    public ProxyInvocationHandler(Object targetObject) {
        this.targetObject = targetObject;
    }
}

实现Invoke方法

 @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(method.getName() + "  >> ========="+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSSS").format(new Date()));

        Object ret = method.invoke(targetObject, args);
        return ret;
    }
  1. Object:实现方法的代理对象
  2. Method:代理实例激发的方法,Porxy参数中的接口方法
  3. Object[]:传递给方法的一系列参数

如何使用这个类呢,

首先创建委托类,实现了接口的方法,然后将委托类传入”代理类“
接下来真正生成代理类,第三个参数即决定了对委托类进行怎样的增强,前两个参数调用的都是委托类的方法:


newProxyInstance,方法有三个参数:

  • loader: 用哪个类加载器去加载代理对象

  • interfaces:动态代理类需要实现的接口

  • h:动态代理方法在执行时,会调用h里面的invoke方法去执行

然后生成了userServiceProxy这个真正的代理类,执行代理类中与接口同样的方法即使增强后的方法,效果如图

https://github.com/MingCaiXiong/spring-learn/commit/9360214425ff69aabb211b7580033c726f858c41