欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

jdk和cglib代理过程详解

程序员文章站 2022-06-21 13:37:40
首先代理的目的都是一样的:就是不修改源代码的基础上,对以有的代码进行扩展。jdk和cglib实现的手段是不一样的。jdk代理是java本身类库包含的一种代理模式,不需要自己导入jar包。下面程序的目的就是返回一个目标类对象target的一个代理对象,target是实现了一个接口的。package com.mec;import com.mec.IDoSomething;public class Target implements IDoSomething { public Target...

首先代理的目的都是一样的:就是不修改源代码的基础上,对以有的代码进行扩展。
jdk和cglib实现的手段是不一样的。

jdk代理是java本身类库包含的一种代理模式,不需要自己导入jar包。
下面程序的目的就是返回一个目标类对象target的一个代理对象,target是实现了一个接口的。

package com.mec;

import com.mec.IDoSomething;

public class Target implements IDoSomething {
    public Target() {
    }

    @Override
    public String doSomething(String str){
        System.out.println(str);
        return "["+str+"]";
    }

    public String test(){
        return "我是test方法";
    }
}

Proxy.newProxyInstance产生一个代理类对象。需要三个参数。

  1. 目标类的类加载器来加载新的代理类(对ClassLoader还不是很了解)
  2. 获取目标类实现的接口,对接口中存在的方法进行扩展。
  3. 并且还需要传入一个InvocationHandler的实现类。
    InvocationHandler是一个接口,是用来控制代理方法具体执行过程的。当通过获取到的代理对象调用方法时,最后都会调用到invoke方法。invoke的三个参数分别是:
    1. proxy真实获取的代理对象,也就是Proxy.newProxyInstance会返回的代理对象。
    2. method是目标类中要被代理扩展的方法,也就是上面target的doSomething方法
    3. args就是method要的参数
public <T> T getJDKProxy(Object target) {
        Class<?> klass = target.getClass();
        ClassLoader classLoader = klass.getClassLoader();
        Class<?>[] interfaces = klass.getInterfaces();

        return (T) Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object res = methodInvoker.invoke(target,method,args);
                return res;
            }
        });
    }

获取到的代理类不仅仅会对接口中的方法进行扩展,因为返回的对象是Object子类,所以对Object的一些方法也都会进行代理,比如toString(),hashcode()等的。
下面我们把动态产生的代理类打印成class文件看一看。

public final String doSomething(String paramString)
    throws 
  {
    try
    {
      return (String)this.h.invoke(this, m3, new Object[] { paramString });
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

被代理的方法有很多,不一一列举。只看我们接口中存在的方法dosomething();
h是Proxy类中的一个InvocationHandler成员变量,最后还是会调用到InvocationHandler的invoke方法,而这个invoke中就可以来写我们的具体代理过程,比如前置拦截和后置拦截等等。

cglib代理是需要外部导入jar包的。
cglib是产生的代理类是目标类的子类。
setCallback是设置方法的拦截器。

public <T> T getCglibProxy(Object target){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(new MethodInterceptor(){
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                Object res = methodInvoker.invoke(target,method,args);
                return res;
            }
        });

        return (T) enhancer.create();
    }

再看一下cglib产生的动态代理类是怎么样的。最后还是调用了Proxy内的h变量。
看了这俩个类,大概就是能理解其中执行的过程了。

import com.mec.Target..EnhancerByCGLIB..c7b51b3d;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.MethodProxy;

public final class $Proxy1 extends Proxy
  implements Target..EnhancerByCGLIB..c7b51b3d
{
  private static Method m1;
  private static Method m3;
  private static Method m6;
  private static Method m2;
  private static Method m8;
  private static Method m12;
  private static Method m18;
  private static Method m20;
  private static Method m0;
  private static Method m15;
  private static Method m11;
  private static Method m9;
  private static Method m7;
  private static Method m19;
  private static Method m10;
  private static Method m5;
  private static Method m17;
  private static Method m16;
  private static Method m13;
  private static Method m14;
  private static Method m4;

  public $Proxy1(InvocationHandler paramInvocationHandler)
    throws 
  {
    super(paramInvocationHandler);
  }

  public final boolean equals(Object paramObject)
    throws 
  {
    try
    {
      return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final Object newInstance(Callback[] paramArrayOfCallback)
    throws 
  {
    try
    {
      return (Object)this.h.invoke(this, m3, new Object[] { paramArrayOfCallback });
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final String test()
    throws 
  {
    try
    {
      return (String)this.h.invoke(this, m6, null);
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final String toString()
    throws 
  {
    try
    {
      return (String)this.h.invoke(this, m2, null);
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final String doSomething(String paramString)
    throws 
  {
    try
    {
      return (String)this.h.invoke(this, m8, new Object[] { paramString });
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final Callback getCallback(int paramInt)
    throws 
  {
    try
    {
      return (Callback)this.h.invoke(this, m12, new Object[] { Integer.valueOf(paramInt) });
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final Class getClass()
    throws 
  {
    try
    {
      return (Class)this.h.invoke(this, m18, null);
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void notifyAll()
    throws 
  {
    try
    {
      this.h.invoke(this, m20, null);
      return;
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final int hashCode()
    throws 
  {
    try
    {
      return ((Integer)this.h.invoke(this, m0, null)).intValue();
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void wait()
    throws InterruptedException
  {
    try
    {
      this.h.invoke(this, m15, null);
      return;
    }
    catch (Error|RuntimeException|InterruptedException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void CGLIB$SET_STATIC_CALLBACKS(Callback[] paramArrayOfCallback)
    throws 
  {
    try
    {
      this.h.invoke(this, m11, new Object[] { paramArrayOfCallback });
      return;
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void setCallbacks(Callback[] paramArrayOfCallback)
    throws 
  {
    try
    {
      this.h.invoke(this, m9, new Object[] { paramArrayOfCallback });
      return;
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void setCallback(int paramInt, Callback paramCallback)
    throws 
  {
    try
    {
      this.h.invoke(this, m7, new Object[] { Integer.valueOf(paramInt), paramCallback });
      return;
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void notify()
    throws 
  {
    try
    {
      this.h.invoke(this, m19, null);
      return;
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void CGLIB$SET_THREAD_CALLBACKS(Callback[] paramArrayOfCallback)
    throws 
  {
    try
    {
      this.h.invoke(this, m10, new Object[] { paramArrayOfCallback });
      return;
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final Object newInstance(Class[] paramArrayOfClass, Object[] paramArrayOfObject, Callback[] paramArrayOfCallback)
    throws 
  {
    try
    {
      return (Object)this.h.invoke(this, m5, new Object[] { paramArrayOfClass, paramArrayOfObject, paramArrayOfCallback });
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void wait(long paramLong)
    throws InterruptedException
  {
    try
    {
      this.h.invoke(this, m17, new Object[] { Long.valueOf(paramLong) });
      return;
    }
    catch (Error|RuntimeException|InterruptedException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void wait(long paramLong, int paramInt)
    throws InterruptedException
  {
    try
    {
      this.h.invoke(this, m16, new Object[] { Long.valueOf(paramLong), Integer.valueOf(paramInt) });
      return;
    }
    catch (Error|RuntimeException|InterruptedException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final Callback[] getCallbacks()
    throws 
  {
    try
    {
      return (Callback[])this.h.invoke(this, m13, null);
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final MethodProxy CGLIB$findMethodProxy(Signature paramSignature)
    throws 
  {
    try
    {
      return (MethodProxy)this.h.invoke(this, m14, new Object[] { paramSignature });
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final Object newInstance(Callback paramCallback)
    throws 
  {
    try
    {
      return (Object)this.h.invoke(this, m4, new Object[] { paramCallback });
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  static
  {
    try
    {
      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
      m3 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("newInstance", new Class[] { Class.forName("[Lnet.sf.cglib.proxy.Callback;") });
      m6 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("test", new Class[0]);
      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
      m8 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("doSomething", new Class[] { Class.forName("java.lang.String") });
      m12 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("getCallback", new Class[] { Integer.TYPE });
      m18 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("getClass", new Class[0]);
      m20 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("notifyAll", new Class[0]);
      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
      m15 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("wait", new Class[0]);
      m11 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("CGLIB$SET_STATIC_CALLBACKS", new Class[] { Class.forName("[Lnet.sf.cglib.proxy.Callback;") });
      m9 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("setCallbacks", new Class[] { Class.forName("[Lnet.sf.cglib.proxy.Callback;") });
      m7 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("setCallback", new Class[] { Integer.TYPE, Class.forName("net.sf.cglib.proxy.Callback") });
      m19 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("notify", new Class[0]);
      m10 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("CGLIB$SET_THREAD_CALLBACKS", new Class[] { Class.forName("[Lnet.sf.cglib.proxy.Callback;") });
      m5 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("newInstance", new Class[] { Class.forName("[Ljava.lang.Class;"), Class.forName("[Ljava.lang.Object;"), Class.forName("[Lnet.sf.cglib.proxy.Callback;") });
      m17 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("wait", new Class[] { Long.TYPE });
      m16 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("wait", new Class[] { Long.TYPE, Integer.TYPE });
      m13 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("getCallbacks", new Class[0]);
      m14 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("CGLIB$findMethodProxy", new Class[] { Class.forName("net.sf.cglib.core.Signature") });
      m4 = Class.forName("com.mec.Target$$EnhancerByCGLIB$$c7b51b3d").getMethod("newInstance", new Class[] { Class.forName("net.sf.cglib.proxy.Callback") });
      return;
    }
    catch (NoSuchMethodException localNoSuchMethodException)
    {
      throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
    }
    catch (ClassNotFoundException localClassNotFoundException)
    {
      throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
    }
  }
}

本文地址:https://blog.csdn.net/Monday__Friday/article/details/107374191

相关标签: java