Java动态代理

  1. 动态代理原理
    为了实现在某各类方法调用的前后做一些事情(输出日志等),同时又不用在改变类的代码,还可以统一操作一批类。
    Java动态代理原理就是动态的生成字节码技术,Java Class其实就是二进制文件,我们可以利用classloader动态加载这个二进制文件,然后生成Java对象,生成原理就是生成Java的各个部分如Java魔数,版本号,各个字段,Java虚方法,构造方法和其他方法。
  2. Java动态原理实现方法
    为一个类生成动态代理的方式有两种:
    基于接口实现:
    jdk动态代理:生成的代理类继承Proxy类,Proxy类里有一个InvocationHandeler h对象,调用代理对象的方法就会调用h.invoke(m,args)方法,具体自己要加的代码在h.invoke方法里写
    生成过程:
    我们知道代理类是通过Proxy类的ProxyClassFactory工厂生成的,这个工厂类会去调用ProxyGenerator类的generateProxyClass()方法来生成代理类的字节码。ProxyGenerator这个类存放在sun.misc包下
private byte[] generateClassFile() {
    //第一步, 将所有的方法组装成ProxyMethod对象
    //首先为代理类生成toString, hashCode, equals等代理方法
    addProxyMethod(hashCodeMethod, Object.class);
    addProxyMethod(equalsMethod, Object.class);
    addProxyMethod(toStringMethod, Object.class);
    //遍历每一个接口的每一个方法, 并且为其生成ProxyMethod对象
    for (int i = 0; i < interfaces.length; i++) {
        Method[] methods = interfaces[i].getMethods();
        for (int j = 0; j < methods.length; j++) {
            addProxyMethod(methods[j], interfaces[i]);
        }
    }
    //对于具有相同签名的代理方法, 检验方法的返回值是否兼容
    for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
        checkReturnTypes(sigmethods);
    }
    
    //第二步, 组装要生成的class文件的所有的字段信息和方法信息
    try {
        //添加构造器方法
        methods.add(generateConstructor());
        //遍历缓存中的代理方法
        for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
            for (ProxyMethod pm : sigmethods) {
                //添加代理类的静态字段, 例如:private static Method m1;
                fields.add(new FieldInfo(pm.methodFieldName,
                        "Ljava/lang/reflect/Method;", ACC_PRIVATE | ACC_STATIC));
                //添加代理类的代理方法
                methods.add(pm.generateMethod());
            }
        }
        //添加代理类的静态字段初始化方法
        methods.add(generateStaticInitializer());
    } catch (IOException e) {
        throw new InternalError("unexpected I/O Exception");
    }
    
    //验证方法和字段集合不能大于65535
    if (methods.size() > 65535) {
        throw new IllegalArgumentException("method limit exceeded");
    }
    if (fields.size() > 65535) {
        throw new IllegalArgumentException("field limit exceeded");
    }

    //第三步, 写入最终的class文件
    //验证常量池中存在代理类的全限定名
    cp.getClass(dotToSlash(className));
    //验证常量池中存在代理类父类的全限定名, 父类名为:"java/lang/reflect/Proxy"
    cp.getClass(superclassName);
    //验证常量池存在代理类接口的全限定名
    for (int i = 0; i < interfaces.length; i++) {
        cp.getClass(dotToSlash(interfaces[i].getName()));
    }
    //接下来要开始写入文件了,设置常量池只读
    cp.setReadOnly();
    
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    DataOutputStream dout = new DataOutputStream(bout);
    try {
        //1.写入魔数
        dout.writeInt(0xCAFEBABE);
        //2.写入次版本号
        dout.writeShort(CLASSFILE_MINOR_VERSION);
        //3.写入主版本号
        dout.writeShort(CLASSFILE_MAJOR_VERSION);
        //4.写入常量池
        cp.write(dout);
        //5.写入访问修饰符
        dout.writeShort(ACC_PUBLIC | ACC_FINAL | ACC_SUPER);
        //6.写入类索引
        dout.writeShort(cp.getClass(dotToSlash(className)));
        //7.写入父类索引, 生成的代理类都继承自Proxy
        dout.writeShort(cp.getClass(superclassName));
        //8.写入接口计数值
        dout.writeShort(interfaces.length);
        //9.写入接口集合
        for (int i = 0; i < interfaces.length; i++) {
            dout.writeShort(cp.getClass(dotToSlash(interfaces[i].getName())));
        }
        //10.写入字段计数值
        dout.writeShort(fields.size());
        //11.写入字段集合 
        for (FieldInfo f : fields) {
            f.write(dout);
        }
        //12.写入方法计数值
        dout.writeShort(methods.size());
        //13.写入方法集合
        for (MethodInfo m : methods) {
            m.write(dout);
        }
        //14.写入属性计数值, 代理类class文件没有属性所以为0
        dout.writeShort(0);
    } catch (IOException e) {
        throw new InternalError("unexpected I/O Exception");
    }
    //转换成二进制数组输出
    return bout.toByteArray();
}

生成结果

import com.foo.proxy.Rechargable;
import com.foo.proxy.Vehicle;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
/**
 生成的动态代理类的组织模式是继承Proxy类,然后实现需要实现代理的类上的所有接口,而在实现的过程中,则是通过将所有的方法都交给了InvocationHandler来处理
*/
 public final class ElectricCarProxy extends Proxy
  implements Rechargable, Vehicle
{
  private static Method m1;
  private static Method m3;
  private static Method m4;
  private static Method m0;
  private static Method m2;
 
  public ElectricCarProxy(InvocationHandler paramInvocationHandler)
    throws 
  {
    super(paramInvocationHandler);
  }
 
  public final boolean equals(Object paramObject)
    throws 
  {
    try
    { // 方法功能实现交给InvocationHandler处理
      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 void recharge()
    throws 
  {
    try
    {
 
       // 方法功能实现交给InvocationHandler处理
 
      this.h.invoke(this, m3, null);
      return;
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
 
  public final void drive()
    throws 
  {
    try
    {
 
       // 方法功能实现交给InvocationHandler处理
 
      this.h.invoke(this, m4, null);
      return;
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
 
  public final int hashCode()
    throws 
  {
    try
    {
 
       // 方法功能实现交给InvocationHandler处理
 
       return ((Integer)this.h.invoke(this, m0, null)).intValue();
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
 
  public final String toString()
    throws 
  {
    try
    {
 
       // 方法功能实现交给InvocationHandler处理
      return (String)this.h.invoke(this, m2, null);
    }
    catch (Error|RuntimeException localError)
    {
      throw localError;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }
 
  static
  {
    try
    {  //为每一个需要方法对象,当调用相应的方法时,分别将方法对象作为参数传递给InvocationHandler处理
      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
      m3 = Class.forName("com.foo.proxy.Rechargable").getMethod("recharge", new Class[0]);
      m4 = Class.forName("com.foo.proxy.Vehicle").getMethod("drive", new Class[0]);
      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
      return;
    }
    catch (NoSuchMethodException localNoSuchMethodException)
    {
      throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
    }
    catch (ClassNotFoundException localClassNotFoundException)
    {
      throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
    }
  }
}

————————————————
版权声明:本文为CSDN博主「亦山」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/luanlouis/article/details/24589193

基于继承实现
cglib方式:cglib基于asm方式实现,asm操作的时汇编语言,使用者必须了解Java class类的结构。
cglib方式不用Java类实现接口,而是生成的代理对象继承自Java类,调用动态代理对象时就是调用super.method();
cglib实现方式:

public class CglabProxyCatTest {
    public static void main(String[] args) {
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\cglib");

        //创建Enhancer对象,类似于JDK动态代理的Proxy类,下一步就是设置几个参数
        Enhancer enhancer = new Enhancer();
        //设置目标类的字节码文件
        enhancer.setSuperclass(Cat.class);
        Cat target = new Cat();
        //设置回调函数
        enhancer.setCallback(new MyMethodInterceptor(target));

        //这里的creat方法就是正式创建代理类
        Cat proxyCat = (Cat) enhancer.create();
        target.setCat(proxyCat);
        //调用代理类的eat方法
        proxyCat.water("huamao");
    }
}
public class MyMethodInterceptor implements MethodInterceptor {

    //被代理对象
    private Object target;

    public MyMethodInterceptor(Object target) {
        this.target = target;
    }

    /**
     *
     * @param o cglig生成的代理对象
     * @param method 被代理对象的方法
     * @param objects 参数
     * @param methodProxy 封装了代理对象和被代理对象class信息
     *                    和方法签名的对象
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("cglib before:" +  method.getName());
        //methodProxy.invokeSuper(o,objects);
        methodProxy.invoke(target,objects);
        //method.invoke(target,objects);
        System.out.println("cglib after" +  method.getName());
        return o;
    }

}

在intercept里有两种调用被代理对象方法的方式,分别为
methodProxy.invokeSuper(o,objects);
methodProxy.invoke(target,objects);
这两种方式差异很大,第一种方式可以在被代理对象内部方法调用也会被增强,而第二种不会,但是spring使用第二种方式,所以在spring框架内使用aop方法内部嵌套增强时,内部调用时不会被增强的;
大致原理如下:
invoke方法传入的是被代理对象Cat,然后在Cat内部的water()方法里调用eat()方法是不会走intercept()方法增强的,invokeSuper传入的是代理对象 Cat E n h a n c e r B y C G L I B EnhancerByCGLIB EnhancerByCGLIB379ad336;我们看下代理对象的eat()方法:

public final void eat(String var1) {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
            var10000.intercept(this, CGLIB$eat$0$Method, new Object[]{var1}, CGLIB$eat$0$Proxy);
        } else {
            super.eat(var1);
        }
    }

还是会调用到MyMethodInterceptor的intercepter方法的;

cglib会生成3个代理对象类,包括两个FastClass和一个代理对象;两个FastClass一个为被代理对象的FastClass,另一个为代理对象的,他们的作用主要是为了快速找到对象里的方法,比反射的效率高点;
在这里插入图片描述
被代理对象的代码为:

public class Cat {
    private Cat cat;

    public void setCat(Object cat) {
        this.cat = (Cat) cat;
    }

    public void eat(String name){
        System.out.println("eat," + name);
    }
    //这种方法嵌套,spring是使用 methodProxy.invoke(target,objects);
    //是无法增强的,而 methodProxy.invokeSuper(o,objects);可以
    public void water(String name) {
        System.out.println("water" + name);
        eat(name);
    }
}

生成的三个类里面的代码为:
代理对象类:

public class Cat$$EnhancerByCGLIB$$379ad336 extends Cat implements Factory {
    private boolean CGLIB$BOUND;
    public static Object CGLIB$FACTORY_DATA;
    private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
    private static final Callback[] CGLIB$STATIC_CALLBACKS;
    private MethodInterceptor CGLIB$CALLBACK_0;
    private static Object CGLIB$CALLBACK_FILTER;
    private static final Method CGLIB$eat$0$Method;
    private static final MethodProxy CGLIB$eat$0$Proxy;
    private static final Object[] CGLIB$emptyArgs;
    private static final Method CGLIB$setCat$1$Method;
    private static final MethodProxy CGLIB$setCat$1$Proxy;
    private static final Method CGLIB$water$2$Method;
    private static final MethodProxy CGLIB$water$2$Proxy;
    private static final Method CGLIB$equals$3$Method;
    private static final MethodProxy CGLIB$equals$3$Proxy;
    private static final Method CGLIB$toString$4$Method;
    private static final MethodProxy CGLIB$toString$4$Proxy;
    private static final Method CGLIB$hashCode$5$Method;
    private static final MethodProxy CGLIB$hashCode$5$Proxy;
    private static final Method CGLIB$clone$6$Method;
    private static final MethodProxy CGLIB$clone$6$Proxy;

    static void CGLIB$STATICHOOK1() {
        CGLIB$THREAD_CALLBACKS = new ThreadLocal();
        CGLIB$emptyArgs = new Object[0];
        Class var0 = Class.forName("com.xiaolong.dto.Cat$$EnhancerByCGLIB$$379ad336");
        Class var1;
        Method[] var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
        CGLIB$equals$3$Method = var10000[0];
        CGLIB$equals$3$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$3");
        CGLIB$toString$4$Method = var10000[1];
        CGLIB$toString$4$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$4");
        CGLIB$hashCode$5$Method = var10000[2];
        CGLIB$hashCode$5$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$5");
        CGLIB$clone$6$Method = var10000[3];
        CGLIB$clone$6$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$6");
        var10000 = ReflectUtils.findMethods(new String[]{"eat", "(Ljava/lang/String;)V", "setCat", "(Ljava/lang/Object;)V", "water", "(Ljava/lang/String;)V"}, (var1 = Class.forName("com.xiaolong.dto.Cat")).getDeclaredMethods());
        CGLIB$eat$0$Method = var10000[0];
        CGLIB$eat$0$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/String;)V", "eat", "CGLIB$eat$0");
        CGLIB$setCat$1$Method = var10000[1];
        CGLIB$setCat$1$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)V", "setCat", "CGLIB$setCat$1");
        CGLIB$water$2$Method = var10000[2];
        CGLIB$water$2$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/String;)V", "water", "CGLIB$water$2");
    }

    final void CGLIB$eat$0(String var1) {
        super.eat(var1);
    }

    public final void eat(String var1) {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
            var10000.intercept(this, CGLIB$eat$0$Method, new Object[]{var1}, CGLIB$eat$0$Proxy);
        } else {
            super.eat(var1);
        }
    }

    final void CGLIB$setCat$1(Object var1) {
        super.setCat(var1);
    }

    public final void setCat(Object var1) {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
            var10000.intercept(this, CGLIB$setCat$1$Method, new Object[]{var1}, CGLIB$setCat$1$Proxy);
        } else {
            super.setCat(var1);
        }
    }

    final void CGLIB$water$2(String var1) {
        super.water(var1);
    }

    public final void water(String var1) {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
            var10000.intercept(this, CGLIB$water$2$Method, new Object[]{var1}, CGLIB$water$2$Proxy);
        } else {
            super.water(var1);
        }
    }

    final boolean CGLIB$equals$3(Object var1) {
        return super.equals(var1);
    }

    public final boolean equals(Object var1) {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
            Object var2 = var10000.intercept(this, CGLIB$equals$3$Method, new Object[]{var1}, CGLIB$equals$3$Proxy);
            return var2 == null ? false : (Boolean)var2;
        } else {
            return super.equals(var1);
        }
    }

    final String CGLIB$toString$4() {
        return super.toString();
    }

    public final String toString() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000 != null ? (String)var10000.intercept(this, CGLIB$toString$4$Method, CGLIB$emptyArgs, CGLIB$toString$4$Proxy) : super.toString();
    }

    final int CGLIB$hashCode$5() {
        return super.hashCode();
    }

    public final int hashCode() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
            Object var1 = var10000.intercept(this, CGLIB$hashCode$5$Method, CGLIB$emptyArgs, CGLIB$hashCode$5$Proxy);
            return var1 == null ? 0 : ((Number)var1).intValue();
        } else {
            return super.hashCode();
        }
    }

    final Object CGLIB$clone$6() throws CloneNotSupportedException {
        return super.clone();
    }

    protected final Object clone() throws CloneNotSupportedException {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000 != null ? var10000.intercept(this, CGLIB$clone$6$Method, CGLIB$emptyArgs, CGLIB$clone$6$Proxy) : super.clone();
    }

    public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
        String var10000 = var0.toString();
        switch(var10000.hashCode()) {
        case -1020676995:
            if (var10000.equals("setCat(Ljava/lang/Object;)V")) {
                return CGLIB$setCat$1$Proxy;
            }
            break;
        case -508378822:
            if (var10000.equals("clone()Ljava/lang/Object;")) {
                return CGLIB$clone$6$Proxy;
            }
            break;
        case -84291256:
            if (var10000.equals("water(Ljava/lang/String;)V")) {
                return CGLIB$water$2$Proxy;
            }
            break;
        case 685027751:
            if (var10000.equals("eat(Ljava/lang/String;)V")) {
                return CGLIB$eat$0$Proxy;
            }
            break;
        case 1826985398:
            if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
                return CGLIB$equals$3$Proxy;
            }
            break;
        case 1913648695:
            if (var10000.equals("toString()Ljava/lang/String;")) {
                return CGLIB$toString$4$Proxy;
            }
            break;
        case 1984935277:
            if (var10000.equals("hashCode()I")) {
                return CGLIB$hashCode$5$Proxy;
            }
        }

        return null;
    }

    public Cat$$EnhancerByCGLIB$$379ad336() {
        CGLIB$BIND_CALLBACKS(this);
    }

    public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
        CGLIB$THREAD_CALLBACKS.set(var0);
    }

    public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) {
        CGLIB$STATIC_CALLBACKS = var0;
    }

    private static final void CGLIB$BIND_CALLBACKS(Object var0) {
        Cat$$EnhancerByCGLIB$$379ad336 var1 = (Cat$$EnhancerByCGLIB$$379ad336)var0;
        if (!var1.CGLIB$BOUND) {
            var1.CGLIB$BOUND = true;
            Object var10000 = CGLIB$THREAD_CALLBACKS.get();
            if (var10000 == null) {
                var10000 = CGLIB$STATIC_CALLBACKS;
                if (var10000 == null) {
                    return;
                }
            }

            var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
        }

    }

    public Object newInstance(Callback[] var1) {
        CGLIB$SET_THREAD_CALLBACKS(var1);
        Cat$$EnhancerByCGLIB$$379ad336 var10000 = new Cat$$EnhancerByCGLIB$$379ad336();
        CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
        return var10000;
    }

    public Object newInstance(Callback var1) {
        CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1});
        Cat$$EnhancerByCGLIB$$379ad336 var10000 = new Cat$$EnhancerByCGLIB$$379ad336();
        CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
        return var10000;
    }

    public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
        CGLIB$SET_THREAD_CALLBACKS(var3);
        Cat$$EnhancerByCGLIB$$379ad336 var10000 = new Cat$$EnhancerByCGLIB$$379ad336;
        switch(var1.length) {
        case 0:
            var10000.<init>();
            CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
            return var10000;
        default:
            throw new IllegalArgumentException("Constructor not found");
        }
    }

    public Callback getCallback(int var1) {
        CGLIB$BIND_CALLBACKS(this);
        MethodInterceptor var10000;
        switch(var1) {
        case 0:
            var10000 = this.CGLIB$CALLBACK_0;
            break;
        default:
            var10000 = null;
        }

        return var10000;
    }

    public void setCallback(int var1, Callback var2) {
        switch(var1) {
        case 0:
            this.CGLIB$CALLBACK_0 = (MethodInterceptor)var2;
        default:
        }
    }

    public Callback[] getCallbacks() {
        CGLIB$BIND_CALLBACKS(this);
        return new Callback[]{this.CGLIB$CALLBACK_0};
    }

    public void setCallbacks(Callback[] var1) {
        this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0];
    }

    static {
        CGLIB$STATICHOOK1();
    }
}

代理对象的FastClass:

public class Cat$$EnhancerByCGLIB$$379ad336$$FastClassByCGLIB$$40e34fe3 extends FastClass {
    public Cat$$EnhancerByCGLIB$$379ad336$$FastClassByCGLIB$$40e34fe3(Class var1) {
        super(var1);
    }

    public int getIndex(Signature var1) {
        String var10000 = var1.toString();
        switch(var10000.hashCode()) {
        case -2071771415:
            if (var10000.equals("CGLIB$clone$6()Ljava/lang/Object;")) {
                return 24;
            }
            break;
        case -2053042819:
            if (var10000.equals("CGLIB$water$2(Ljava/lang/String;)V")) {
                return 19;
            }
            break;
        case -1870561232:
            if (var10000.equals("CGLIB$findMethodProxy(Lorg/springframework/cglib/core/Signature;)Lorg/springframework/cglib/proxy/MethodProxy;")) {
                return 16;
            }
            break;
        case -1745842178:
            if (var10000.equals("setCallbacks([Lorg/springframework/cglib/proxy/Callback;)V")) {
                return 7;
            }
            break;
        case -1663710620:
            if (var10000.equals("CGLIB$equals$3(Ljava/lang/Object;)Z")) {
                return 20;
            }
            break;
        case -1641413109:
            if (var10000.equals("newInstance([Lorg/springframework/cglib/proxy/Callback;)Ljava/lang/Object;")) {
                return 4;
            }
            break;
        case -1457535688:
            if (var10000.equals("CGLIB$STATICHOOK1()V")) {
                return 22;
            }
            break;
        case -1411783143:
            if (var10000.equals("CGLIB$hashCode$5()I")) {
                return 23;
            }
            break;
        case -1034266769:
            if (var10000.equals("CGLIB$SET_STATIC_CALLBACKS([Lorg/springframework/cglib/proxy/Callback;)V")) {
                return 15;
            }
            break;
        case -1025895669:
            if (var10000.equals("CGLIB$SET_THREAD_CALLBACKS([Lorg/springframework/cglib/proxy/Callback;)V")) {
                return 14;
            }
            break;
        case -1020676995:
            if (var10000.equals("setCat(Ljava/lang/Object;)V")) {
                return 11;
            }
            break;
        case -988317324:
            if (var10000.equals("newInstance([Ljava/lang/Class;[Ljava/lang/Object;[Lorg/springframework/cglib/proxy/Callback;)Ljava/lang/Object;")) {
                return 6;
            }
            break;
        case -508378822:
            if (var10000.equals("clone()Ljava/lang/Object;")) {
                return 3;
            }
            break;
        case -433745506:
            if (var10000.equals("CGLIB$eat$0(Ljava/lang/String;)V")) {
                return 17;
            }
            break;
        case -84291256:
            if (var10000.equals("water(Ljava/lang/String;)V")) {
                return 12;
            }
            break;
        case 610042816:
            if (var10000.equals("newInstance(Lorg/springframework/cglib/proxy/Callback;)Ljava/lang/Object;")) {
                return 5;
            }
            break;
        case 685027751:
            if (var10000.equals("eat(Ljava/lang/String;)V")) {
                return 10;
            }
            break;
        case 1132856532:
            if (var10000.equals("getCallbacks()[Lorg/springframework/cglib/proxy/Callback;")) {
                return 9;
            }
            break;
        case 1246779367:
            if (var10000.equals("setCallback(ILorg/springframework/cglib/proxy/Callback;)V")) {
                return 13;
            }
            break;
        case 1364367423:
            if (var10000.equals("getCallback(I)Lorg/springframework/cglib/proxy/Callback;")) {
                return 8;
            }
            break;
        case 1703013677:
            if (var10000.equals("CGLIB$setCat$1(Ljava/lang/Object;)V")) {
                return 18;
            }
            break;
        case 1729170762:
            if (var10000.equals("CGLIB$toString$4()Ljava/lang/String;")) {
                return 21;
            }
            break;
        case 1826985398:
            if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
                return 0;
            }
            break;
        case 1913648695:
            if (var10000.equals("toString()Ljava/lang/String;")) {
                return 1;
            }
            break;
        case 1984935277:
            if (var10000.equals("hashCode()I")) {
                return 2;
            }
        }

        return -1;
    }

    public int getIndex(String var1, Class[] var2) {
        switch(var1.hashCode()) {
        case -2083343934:
            if (var1.equals("CGLIB$water$2")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.String")) {
                        return 19;
                    }
                }
            }
            break;
        case -1776922004:
            if (var1.equals("toString")) {
                switch(var2.length) {
                case 0:
                    return 1;
                }
            }
            break;
        case -1295482945:
            if (var1.equals("equals")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.Object")) {
                        return 0;
                    }
                }
            }
            break;
        case -1053468136:
            if (var1.equals("getCallbacks")) {
                switch(var2.length) {
                case 0:
                    return 9;
                }
            }
            break;
        case -905816044:
            if (var1.equals("setCat")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.Object")) {
                        return 11;
                    }
                }
            }
            break;
        case -124978607:
            if (var1.equals("CGLIB$equals$3")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.Object")) {
                        return 20;
                    }
                }
            }
            break;
        case -60403779:
            if (var1.equals("CGLIB$SET_STATIC_CALLBACKS")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("[Lorg.springframework.cglib.proxy.Callback;")) {
                        return 15;
                    }
                }
            }
            break;
        case -29025553:
            if (var1.equals("CGLIB$hashCode$5")) {
                switch(var2.length) {
                case 0:
                    return 23;
                }
            }
            break;
        case 100184:
            if (var1.equals("eat")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.String")) {
                        return 10;
                    }
                }
            }
            break;
        case 85179481:
            if (var1.equals("CGLIB$SET_THREAD_CALLBACKS")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("[Lorg.springframework.cglib.proxy.Callback;")) {
                        return 14;
                    }
                }
            }
            break;
        case 94756189:
            if (var1.equals("clone")) {
                switch(var2.length) {
                case 0:
                    return 3;
                }
            }
            break;
        case 112903447:
            if (var1.equals("water")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.String")) {
                        return 12;
                    }
                }
            }
            break;
        case 147696667:
            if (var1.equals("hashCode")) {
                switch(var2.length) {
                case 0:
                    return 2;
                }
            }
            break;
        case 161998109:
            if (var1.equals("CGLIB$STATICHOOK1")) {
                switch(var2.length) {
                case 0:
                    return 22;
                }
            }
            break;
        case 495524492:
            if (var1.equals("setCallbacks")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("[Lorg.springframework.cglib.proxy.Callback;")) {
                        return 7;
                    }
                }
            }
            break;
        case 682758500:
            if (var1.equals("CGLIB$setCat$1")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.Object")) {
                        return 18;
                    }
                }
            }
            break;
        case 1111931649:
            if (var1.equals("CGLIB$eat$0")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.String")) {
                        return 17;
                    }
                }
            }
            break;
        case 1154623345:
            if (var1.equals("CGLIB$findMethodProxy")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("org.springframework.cglib.core.Signature")) {
                        return 16;
                    }
                }
            }
            break;
        case 1543336191:
            if (var1.equals("CGLIB$toString$4")) {
                switch(var2.length) {
                case 0:
                    return 21;
                }
            }
            break;
        case 1811874389:
            if (var1.equals("newInstance")) {
                switch(var2.length) {
                case 1:
                    String var10001 = var2[0].getName();
                    switch(var10001.hashCode()) {
                    case -1997738671:
                        if (var10001.equals("[Lorg.springframework.cglib.proxy.Callback;")) {
                            return 4;
                        }
                        break;
                    case 1364160985:
                        if (var10001.equals("org.springframework.cglib.proxy.Callback")) {
                            return 5;
                        }
                    }
                case 2:
                default:
                    break;
                case 3:
                    if (var2[0].getName().equals("[Ljava.lang.Class;") && var2[1].getName().equals("[Ljava.lang.Object;") && var2[2].getName().equals("[Lorg.springframework.cglib.proxy.Callback;")) {
                        return 6;
                    }
                }
            }
            break;
        case 1817099975:
            if (var1.equals("setCallback")) {
                switch(var2.length) {
                case 2:
                    if (var2[0].getName().equals("int") && var2[1].getName().equals("org.springframework.cglib.proxy.Callback")) {
                        return 13;
                    }
                }
            }
            break;
        case 1905679803:
            if (var1.equals("getCallback")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("int")) {
                        return 8;
                    }
                }
            }
            break;
        case 1951977612:
            if (var1.equals("CGLIB$clone$6")) {
                switch(var2.length) {
                case 0:
                    return 24;
                }
            }
        }

        return -1;
    }

    public int getIndex(Class[] var1) {
        switch(var1.length) {
        case 0:
            return 0;
        default:
            return -1;
        }
    }

    public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
        379ad336 var10000 = (379ad336)var2;
        int var10001 = var1;

        try {
            switch(var10001) {
            case 0:
                return new Boolean(var10000.equals(var3[0]));
            case 1:
                return var10000.toString();
            case 2:
                return new Integer(var10000.hashCode());
            case 3:
                return var10000.clone();
            case 4:
                return var10000.newInstance((Callback[])var3[0]);
            case 5:
                return var10000.newInstance((Callback)var3[0]);
            case 6:
                return var10000.newInstance((Class[])var3[0], (Object[])var3[1], (Callback[])var3[2]);
            case 7:
                var10000.setCallbacks((Callback[])var3[0]);
                return null;
            case 8:
                return var10000.getCallback(((Number)var3[0]).intValue());
            case 9:
                return var10000.getCallbacks();
            case 10:
                var10000.eat((String)var3[0]);
                return null;
            case 11:
                var10000.setCat(var3[0]);
                return null;
            case 12:
                var10000.water((String)var3[0]);
                return null;
            case 13:
                var10000.setCallback(((Number)var3[0]).intValue(), (Callback)var3[1]);
                return null;
            case 14:
                379ad336.CGLIB$SET_THREAD_CALLBACKS((Callback[])var3[0]);
                return null;
            case 15:
                379ad336.CGLIB$SET_STATIC_CALLBACKS((Callback[])var3[0]);
                return null;
            case 16:
                return 379ad336.CGLIB$findMethodProxy((Signature)var3[0]);
            case 17:
                var10000.CGLIB$eat$0((String)var3[0]);
                return null;
            case 18:
                var10000.CGLIB$setCat$1(var3[0]);
                return null;
            case 19:
                var10000.CGLIB$water$2((String)var3[0]);
                return null;
            case 20:
                return new Boolean(var10000.CGLIB$equals$3(var3[0]));
            case 21:
                return var10000.CGLIB$toString$4();
            case 22:
                379ad336.CGLIB$STATICHOOK1();
                return null;
            case 23:
                return new Integer(var10000.CGLIB$hashCode$5());
            case 24:
                return var10000.CGLIB$clone$6();
            }
        } catch (Throwable var4) {
            throw new InvocationTargetException(var4);
        }

        throw new IllegalArgumentException("Cannot find matching method/constructor");
    }

    public Object newInstance(int var1, Object[] var2) throws InvocationTargetException {
        379ad336 var10000 = new 379ad336;
        379ad336 var10001 = var10000;
        int var10002 = var1;

        try {
            switch(var10002) {
            case 0:
                var10001.<init>();
                return var10000;
            }
        } catch (Throwable var3) {
            throw new InvocationTargetException(var3);
        }

        throw new IllegalArgumentException("Cannot find matching method/constructor");
    }

    public int getMaxIndex() {
        return 24;
    }
}

被代理对象的FastClass:

public class Cat$$FastClassByCGLIB$$160d4ae1 extends FastClass {
    public Cat$$FastClassByCGLIB$$160d4ae1(Class var1) {
        super(var1);
    }

    public int getIndex(Signature var1) {
        String var10000 = var1.toString();
        switch(var10000.hashCode()) {
        case -1020676995:
            if (var10000.equals("setCat(Ljava/lang/Object;)V")) {
                return 1;
            }
            break;
        case -84291256:
            if (var10000.equals("water(Ljava/lang/String;)V")) {
                return 2;
            }
            break;
        case 685027751:
            if (var10000.equals("eat(Ljava/lang/String;)V")) {
                return 0;
            }
            break;
        case 1826985398:
            if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
                return 3;
            }
            break;
        case 1913648695:
            if (var10000.equals("toString()Ljava/lang/String;")) {
                return 4;
            }
            break;
        case 1984935277:
            if (var10000.equals("hashCode()I")) {
                return 5;
            }
        }

        return -1;
    }

    public int getIndex(String var1, Class[] var2) {
        switch(var1.hashCode()) {
        case -1776922004:
            if (var1.equals("toString")) {
                switch(var2.length) {
                case 0:
                    return 4;
                }
            }
            break;
        case -1295482945:
            if (var1.equals("equals")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.Object")) {
                        return 3;
                    }
                }
            }
            break;
        case -905816044:
            if (var1.equals("setCat")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.Object")) {
                        return 1;
                    }
                }
            }
            break;
        case 100184:
            if (var1.equals("eat")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.String")) {
                        return 0;
                    }
                }
            }
            break;
        case 112903447:
            if (var1.equals("water")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.String")) {
                        return 2;
                    }
                }
            }
            break;
        case 147696667:
            if (var1.equals("hashCode")) {
                switch(var2.length) {
                case 0:
                    return 5;
                }
            }
        }

        return -1;
    }

    public int getIndex(Class[] var1) {
        switch(var1.length) {
        case 0:
            return 0;
        default:
            return -1;
        }
    }

    public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
        Cat var10000 = (Cat)var2;
        int var10001 = var1;

        try {
            switch(var10001) {
            case 0:
                var10000.eat((String)var3[0]);
                return null;
            case 1:
                var10000.setCat(var3[0]);
                return null;
            case 2:
                var10000.water((String)var3[0]);
                return null;
            case 3:
                return new Boolean(var10000.equals(var3[0]));
            case 4:
                return var10000.toString();
            case 5:
                return new Integer(var10000.hashCode());
            }
        } catch (Throwable var4) {
            throw new InvocationTargetException(var4);
        }

        throw new IllegalArgumentException("Cannot find matching method/constructor");
    }

    public Object newInstance(int var1, Object[] var2) throws InvocationTargetException {
        Cat var10000 = new Cat;
        Cat var10001 = var10000;
        int var10002 = var1;

        try {
            switch(var10002) {
            case 0:
                var10001.<init>();
                return var10000;
            }
        } catch (Throwable var3) {
            throw new InvocationTargetException(var3);
        }

        throw new IllegalArgumentException("Cannot find matching method/constructor");
    }

    public int getMaxIndex() {
        return 5;
    }
}

3.两种方式对比
jdk动态代理要求代理对象必须实现接口,有一定的局限性,而cglib则无此要求,但是cglib依赖于第三方jar包,并且cglib提供的invokeSuper方法可以实现内部嵌套增强,而jdk无此方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值