Spring-8-JDK动态代理

JDK动态代理分步使用步骤

  • 通过实现InvocationHandler接口来自定义自己的InvocationHandler(在InvocationHandler初始化对象时绑定target)
public class HWInvocationHandler implements InvocationHandler {
  private Object target;
  public HWInvocationHandler (Object target) {
    this.target = target;
  }
  public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
    System.out.println("-----插入前置通知代码-----");
    Object re = method.invoke(target, args);
    System.out.println("-----插入后置处理代码-----");
    return rs;
  }
}
  • 通过Proxy.getProxyClass获得动态代理类的Class对象,参数:类加载器,接口列表
public void test() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
  System.getProperties.put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
  Class proxyClazz = Proxy.getProxyClass(IHello.class.getClassLoader(), new Class[]{ IHello.class });
  Constructor constructor = proxyClazz.getConstructor(InvocationHandler.class);
  IHello ihello = (IHello) constructor.newInstance(new HWInvocationHandler(new Hello()));
  ihello.sayHello();
}
  • 通过反射机制获得代理类的构造方法,方法签名为getConstructor(InvocationHandler.class)
  • 通过构造函数的newInstance获得代理对象,参数就是自定义的InvocationHandler
  • 通过代理对象调用目标方法,代理对象与目标对象的同名方法中,执行其持有的InvocationHandler(这个对象是在Proxy中声明的属性,被代理类继承过来了)对象的invoke方法
  • 说明
IHello // 接口
Hello // 业务实现类业务
public final class $Proxy0 extends Proxy implements IHello // 生成的代理类$Proxy0

public $Proxy0 (InvocationHandler paramInvocationHandler) {
  super(paramInvocationHandler); //代理类的构造函数直接用父类Proxy的
}
protected Proxy (InvocationHandler h) {
  Objects.requireNonNull(h);
  this.h = h;
}

Proxy.newProxyInstance

  • Proxy中,有一个封装的方法来一步到位的生成代理对象
public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
IHello ihello = (IHello) Proxy.newProxyInstance(IHello.class.getClassLoader(), new Class[] {IHello.class}, new InvocationHandler(new Hello()));
ihello.sayHello();

Spring里的代码流程

  • 下面的JDK动态代理原理逻辑分析就以newProxyInstance来展开了,虽然和上面的分步式存在一些代码差别,但原理是一致的
public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
  • Proxy.newProxyInstance(classLoader, proxiedInterfaces, this)
    • this就是JdkDynamicAopProxy本身
    • Class cl = getProxyClass0(loader, intfs);
  • Proxy.getProxyClass0
    • return proxyClassCache.get(loader, interfaces);
  • Weakcache.get
    • V value = supplier.get();
  • WeakCache$Factory.get
    • value = Objects.requireNonNull(valueFactory.apply(key, parameter));
  • Proxy$ProxyClassFactory.apply
    • byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);
package com.sun.proxy;

import com.fjh.aop.ITarget;
import com.fjh.aop.ITarget2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy2 extends Proxy implements ITarget, ITarget2 {
    private static Method m1;
    private static Method m4;
    private static Method m2;
    private static Method m3;
    private static Method m0;

    public $Proxy2(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void target2() throws  {
        try {
            super.h.invoke(this, m4, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final void target() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m4 = Class.forName("com.fjh.aop.ITarget2").getMethod("target2");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("com.fjh.aop.ITarget").getMethod("target");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

你可能感兴趣的:(Spring-8-JDK动态代理)