JDK与cglib动态代理

news2024/11/24 22:28:17

JDK动态代理

接口类

public interface Subject {

    void doSomething();
}

接口实现

public class RealSubject implements Subject {
    @Override
    public void doSomething() {
        System.out.println("RealSubject do something");
    }
}

InvocationHandler类

package daili;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * JDKDynamicProxy
 * jdkd动态代理
 *
 * @author
 * @create 2018-03-29 16:17
 **/
public class JDKDynamicProxy implements InvocationHandler {

    private Object target;

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

    /**
     * 获取被代理接口实例对象
     * @param <T>
     * @return
     */
    public <T> T getProxy() {
        return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

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

使用方法

package daili;


public class Test {
    public static void main(String[] args) {
        // 保存生成的代理类的字节码文件
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

        // jdk动态代理测试
        Subject subject = new JDKDynamicProxy(new RealSubject()).getProxy();
        subject.doSomething();
    }
}

看下其生成的代理类字节码

JDK代理类字节码

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.sun.proxy;

import daili.Subject;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements Subject {
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m0;

    public $Proxy0(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 doSomething() throws  {
        try {
            super.h.invoke(this, m3, (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 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"));
            m3 = Class.forName("daili.Subject").getMethod("doSomething");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}


代理类必须继承自接口。可以看出来jdk的代理类切面逻辑由InvocationHandler实现,

Proxy0代理类构造入参是InvocationHandler,根据需要被代理的类继承的接口生成方法,当接口方法被调用时,执行InvocationHandler的invoke方法invoke方法

 try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m3 = Class.forName("daili.Subject").getMethod("doSomething");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } 

可以看出,除了目标接口方法,还对equals,toString,hashCode与对象有关的方法进行特殊处理,通过handler进行处理。

invoke方法三个参数

参数1 代理类本身
参数2 调用的对应接口方法
参数3 方法的入参数组

cglib动态代理

拦截目标类

public class Student{
    public void say() {
        System.out.println("我是学生...");
        test();
    }

    public void test() {
        System.out.println("test");
    }
}

拦截器


public class CglibProxy implements MethodInterceptor {

    /**
     * 重写方法拦截在方法前和方法后加入业务
     * Object obj为目标对象
     * Method method为目标方法
     * Object[] params 为参数,
     * MethodProxy proxy CGlib方法代理对象
     */
    @Override
    public Object intercept(Object obj, Method method, Object[] args,
                            MethodProxy methodProxy) throws Throwable {
        System.out.println("===============");
        return methodProxy.invokeSuper(obj, args);
    }
}

使用方法

public class CglibProxyTest {

    public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
        // 生成class类的路径
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D://temp");
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Student.class);
        enhancer.setCallback(new CglibProxy());

        Student student = (Student) enhancer.create();
        student.say();
    }
}

代理类字节码文件

首先需要先说一下FastClass。在使用Cglib动态代理时会生成3个新类,如下图所示。
第一个文件:代理类的FastClass类
第二个文件:代理类,继承自被代理类
第三个文件:被代理类的FastClass类
在这里插入图片描述

FastClass类主要实现了字节码与执行方法的索引关系。大致果然如下图所示,“字符串”与“对象”分别的两个过程的主要入参。cglib代理以这种方式避免了对被代理对象的反射调用,这也是cglib性能较优于JDK代理的地方。

委托类字节码

首先执行的的是委托类

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package daili.cglib;

import java.lang.reflect.Method;
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class Student$$EnhancerByCGLIB$$2276c04 extends Student implements Factory {
    private boolean CGLIB$BOUND;
    private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
    private static final Callback[] CGLIB$STATIC_CALLBACKS;
    private MethodInterceptor CGLIB$CALLBACK_0;
    private static final Method CGLIB$test$0$Method;
    private static final MethodProxy CGLIB$test$0$Proxy;
    private static final Object[] CGLIB$emptyArgs;
    private static final Method CGLIB$say$1$Method;
    private static final MethodProxy CGLIB$say$1$Proxy;
    private static final Method CGLIB$finalize$2$Method;
    private static final MethodProxy CGLIB$finalize$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("daili.cglib.Student$$EnhancerByCGLIB$$2276c04");
        Class var1;
        Method[] var10000 = ReflectUtils.findMethods(new String[]{"finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
        CGLIB$finalize$2$Method = var10000[0];
        CGLIB$finalize$2$Proxy = MethodProxy.create(var1, var0, "()V", "finalize", "CGLIB$finalize$2");
        CGLIB$equals$3$Method = var10000[1];
        CGLIB$equals$3$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$3");
        CGLIB$toString$4$Method = var10000[2];
        CGLIB$toString$4$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$4");
        CGLIB$hashCode$5$Method = var10000[3];
        CGLIB$hashCode$5$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$5");
        CGLIB$clone$6$Method = var10000[4];
        CGLIB$clone$6$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$6");
        var10000 = ReflectUtils.findMethods(new String[]{"test", "()V", "say", "()V"}, (var1 = Class.forName("daili.cglib.Student")).getDeclaredMethods());
        CGLIB$test$0$Method = var10000[0];
        CGLIB$test$0$Proxy = MethodProxy.create(var1, var0, "()V", "test", "CGLIB$test$0");
        CGLIB$say$1$Method = var10000[1];
        CGLIB$say$1$Proxy = MethodProxy.create(var1, var0, "()V", "say", "CGLIB$say$1");
    }

    final void CGLIB$test$0() {
        super.test();
    }

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

        if (var10000 != null) {
            var10000.intercept(this, CGLIB$test$0$Method, CGLIB$emptyArgs, CGLIB$test$0$Proxy);
        } else {
            super.test();
        }
    }

    final void CGLIB$say$1() {
        super.say();
    }

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

        if (var10000 != null) {
            var10000.intercept(this, CGLIB$say$1$Method, CGLIB$emptyArgs, CGLIB$say$1$Proxy);
        } else {
            super.say();
        }
    }

    final void CGLIB$finalize$2() throws Throwable {
        super.finalize();
    }

    protected final void finalize() throws Throwable {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (this.CGLIB$CALLBACK_0 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
            var10000.intercept(this, CGLIB$finalize$2$Method, CGLIB$emptyArgs, CGLIB$finalize$2$Proxy);
        } else {
            super.finalize();
        }
    }

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

    public final boolean equals(Object var1) {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (this.CGLIB$CALLBACK_0 == 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 (this.CGLIB$CALLBACK_0 == 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 (this.CGLIB$CALLBACK_0 == 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 (this.CGLIB$CALLBACK_0 == 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 -1574182249:
            if (var10000.equals("finalize()V")) {
                return CGLIB$finalize$2$Proxy;
            }
            break;
        case -1422510685:
            if (var10000.equals("test()V")) {
                return CGLIB$test$0$Proxy;
            }
            break;
        case -909388886:
            if (var10000.equals("say()V")) {
                return CGLIB$say$1$Proxy;
            }
            break;
        case -508378822:
            if (var10000.equals("clone()Ljava/lang/Object;")) {
                return CGLIB$clone$6$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 Student$$EnhancerByCGLIB$$2276c04() {
        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) {
        Student$$EnhancerByCGLIB$$2276c04 var1 = (Student$$EnhancerByCGLIB$$2276c04)var0;
        if (!var1.CGLIB$BOUND) {
            var1.CGLIB$BOUND = true;
            Object var10000 = CGLIB$THREAD_CALLBACKS.get();
            if (var10000 == null) {
                var10000 = CGLIB$STATIC_CALLBACKS;
                if (CGLIB$STATIC_CALLBACKS == null) {
                    return;
                }
            }

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

    }

    public Object newInstance(Callback[] var1) {
        CGLIB$SET_THREAD_CALLBACKS(var1);
        Student$$EnhancerByCGLIB$$2276c04 var10000 = new Student$$EnhancerByCGLIB$$2276c04();
        CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
        return var10000;
    }

    public Object newInstance(Callback var1) {
        CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1});
        Student$$EnhancerByCGLIB$$2276c04 var10000 = new Student$$EnhancerByCGLIB$$2276c04();
        CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
        return var10000;
    }

    public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
        CGLIB$SET_THREAD_CALLBACKS(var3);
        Student$$EnhancerByCGLIB$$2276c04 var10000 = new Student$$EnhancerByCGLIB$$2276c04;
        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();
    }
}


委托类继承了目标类,并且实现了目标类的所有方法、
可以看出Cglib生的字节码继承所有的父类方法, 对于每个方法,会进入切面处理器
以say方法为例

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

        if (var10000 != null) {
            var10000.intercept(this, CGLIB$say$1$Method, CGLIB$emptyArgs, CGLIB$say$1$Proxy);
        } else {
            super.say();
        }
    }

如果委托的代理类里的MethodInterceptor为空,那么直接直接执行父类,否则执行切面

进入切面方法

   @Override
    public Object intercept(Object obj, Method method, Object[] args,
                            MethodProxy methodProxy) throws Throwable {
        System.out.println("===============");
        return methodProxy.invokeSuper(obj, args);
    }

参数1 委托代理类
参数2 被代理类的执行方法
参数3 方法参数
参数4 代理类方法MethodProxy可以进行invoke和invokeSuper再次对代理类进行执行
看下MethodProxy中invokeSuper方法

 public Object invokeSuper(Object obj, Object[] args) throws Throwable {
        try {
            this.init();
            MethodProxy.FastClassInfo fci = this.fastClassInfo;
            return fci.f2.invoke(fci.i2, obj, args);
        } catch (InvocationTargetException var4) {
            throw var4.getTargetException();
        }
    }

通过fastClass执行实例的方法
和invoke方法的区别

public Object invoke(Object obj, Object[] args) throws Throwable {
        try {
            this.init();
            MethodProxy.FastClassInfo fci = this.fastClassInfo;
            return fci.f1.invoke(fci.i1, obj, args);
        } catch (InvocationTargetException var4) {
            throw var4.getTargetException();
        } catch (IllegalArgumentException var5) {
            if (this.fastClassInfo.i1 < 0) {
                throw new IllegalArgumentException("Protected method: " + this.sig1);
            } else {
                throw var5;
            }
        }
    }


区别是两者都使用的是FastClassInfo进行invoke,区别是i1调用的是委托类的对应方法,而i2调用的是父类对应方法
注意如果使用invoke继续调用代理类中的方法,走代理逻辑,那么又会进入方法拦截器,发生四递归,导致堆栈溢出。一般情况下都会使用invokeSuper方法

fastClass机制介绍

MethodProxy执行invoke和invokeSuper之后,会分别执行对应的fastClass
在这里插入图片描述

Jdk动态代理的拦截对象是通过反射的机制来调用被拦截实例方法的,反射的效率比较低,所以cglib采用了FastClass的机制来实现对被拦截方法的调用。FastClass机制就是对一个类的方法建立索引,调用方法时根据方法的签名来计算索引,通过索引来直接调用相应的方法。
这也就是为什么CGLIB生成的动态代理会包含3个class文件的原因,其中一个是生成的代理类,另外两个类都是FastClass机制需要的。另外两个类都继承了FastClass这个类。其中一个class为生成的代理类中的每个方法建立了索引(invoke方法执行),另外一个则为我们被代理类的所有方法包含其父类的方法建立了索引(invokeSuper方法执行)。
下面这个就是为被代理类中的方法建立的索引。



package daili.cglib;

import daili.cglib.Student..EnhancerByCGLIB..2276c04;
import java.lang.reflect.InvocationTargetException;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.reflect.FastClass;

public class Student$$EnhancerByCGLIB$$2276c04$$FastClassByCGLIB$$6504760b extends FastClass {
    public Student$$EnhancerByCGLIB$$2276c04$$FastClassByCGLIB$$6504760b(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 21;
            }
            break;
        case -2055565910:
            if (var10000.equals("CGLIB$SET_THREAD_CALLBACKS([Lnet/sf/cglib/proxy/Callback;)V")) {
                return 10;
            }
            break;
        case -1725733088:
            if (var10000.equals("getClass()Ljava/lang/Class;")) {
                return 26;
            }
            break;
        case -1663710620:
            if (var10000.equals("CGLIB$equals$3(Ljava/lang/Object;)Z")) {
                return 19;
            }
            break;
        case -1659809612:
            if (var10000.equals("CGLIB$test$0()V")) {
                return 20;
            }
            break;
        case -1457535688:
            if (var10000.equals("CGLIB$STATICHOOK1()V")) {
                return 22;
            }
            break;
        case -1422510685:
            if (var10000.equals("test()V")) {
                return 6;
            }
            break;
        case -1411783143:
            if (var10000.equals("CGLIB$hashCode$5()I")) {
                return 18;
            }
            break;
        case -1026001249:
            if (var10000.equals("wait(JI)V")) {
                return 24;
            }
            break;
        case -909388886:
            if (var10000.equals("say()V")) {
                return 7;
            }
            break;
        case -894172689:
            if (var10000.equals("newInstance(Lnet/sf/cglib/proxy/Callback;)Ljava/lang/Object;")) {
                return 4;
            }
            break;
        case -623122092:
            if (var10000.equals("CGLIB$findMethodProxy(Lnet/sf/cglib/core/Signature;)Lnet/sf/cglib/proxy/MethodProxy;")) {
                return 14;
            }
            break;
        case -419626537:
            if (var10000.equals("setCallbacks([Lnet/sf/cglib/proxy/Callback;)V")) {
                return 9;
            }
            break;
        case 243996900:
            if (var10000.equals("wait(J)V")) {
                return 25;
            }
            break;
        case 560567118:
            if (var10000.equals("setCallback(ILnet/sf/cglib/proxy/Callback;)V")) {
                return 8;
            }
            break;
        case 811063227:
            if (var10000.equals("newInstance([Ljava/lang/Class;[Ljava/lang/Object;[Lnet/sf/cglib/proxy/Callback;)Ljava/lang/Object;")) {
                return 5;
            }
            break;
        case 946854621:
            if (var10000.equals("notifyAll()V")) {
                return 28;
            }
            break;
        case 973717575:
            if (var10000.equals("getCallbacks()[Lnet/sf/cglib/proxy/Callback;")) {
                return 12;
            }
            break;
        case 1116248544:
            if (var10000.equals("wait()V")) {
                return 23;
            }
            break;
        case 1221173700:
            if (var10000.equals("newInstance([Lnet/sf/cglib/proxy/Callback;)Ljava/lang/Object;")) {
                return 3;
            }
            break;
        case 1230699260:
            if (var10000.equals("getCallback(I)Lnet/sf/cglib/proxy/Callback;")) {
                return 13;
            }
            break;
        case 1365107430:
            if (var10000.equals("CGLIB$finalize$2()V")) {
                return 16;
            }
            break;
        case 1540724864:
            if (var10000.equals("CGLIB$say$1()V")) {
                return 15;
            }
            break;
        case 1584330438:
            if (var10000.equals("CGLIB$SET_STATIC_CALLBACKS([Lnet/sf/cglib/proxy/Callback;)V")) {
                return 11;
            }
            break;
        case 1729170762:
            if (var10000.equals("CGLIB$toString$4()Ljava/lang/String;")) {
                return 17;
            }
            break;
        case 1826985398:
            if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
                return 0;
            }
            break;
        case 1902039948:
            if (var10000.equals("notify()V")) {
                return 27;
            }
            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 -2083498449:
            if (var1.equals("CGLIB$finalize$2")) {
                switch(var2.length) {
                case 0:
                    return 16;
                }
            }
            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 12;
                }
            }
            break;
        case -1039689911:
            if (var1.equals("notify")) {
                switch(var2.length) {
                case 0:
                    return 27;
                }
            }
            break;
        case -124978607:
            if (var1.equals("CGLIB$equals$3")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.Object")) {
                        return 19;
                    }
                }
            }
            break;
        case -60403779:
            if (var1.equals("CGLIB$SET_STATIC_CALLBACKS")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("[Lnet.sf.cglib.proxy.Callback;")) {
                        return 11;
                    }
                }
            }
            break;
        case -29025553:
            if (var1.equals("CGLIB$hashCode$5")) {
                switch(var2.length) {
                case 0:
                    return 18;
                }
            }
            break;
        case 113643:
            if (var1.equals("say")) {
                switch(var2.length) {
                case 0:
                    return 7;
                }
            }
            break;
        case 3556498:
            if (var1.equals("test")) {
                switch(var2.length) {
                case 0:
                    return 6;
                }
            }
            break;
        case 3641717:
            if (var1.equals("wait")) {
                switch(var2.length) {
                case 0:
                    return 23;
                case 1:
                    if (var2[0].getName().equals("long")) {
                        return 25;
                    }
                    break;
                case 2:
                    if (var2[0].getName().equals("long") && var2[1].getName().equals("int")) {
                        return 24;
                    }
                }
            }
            break;
        case 85179481:
            if (var1.equals("CGLIB$SET_THREAD_CALLBACKS")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("[Lnet.sf.cglib.proxy.Callback;")) {
                        return 10;
                    }
                }
            }
            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("[Lnet.sf.cglib.proxy.Callback;")) {
                        return 9;
                    }
                }
            }
            break;
        case 543320865:
            if (var1.equals("CGLIB$test$0")) {
                switch(var2.length) {
                case 0:
                    return 20;
                }
            }
            break;
        case 1124865749:
            if (var1.equals("CGLIB$say$1")) {
                switch(var2.length) {
                case 0:
                    return 15;
                }
            }
            break;
        case 1154623345:
            if (var1.equals("CGLIB$findMethodProxy")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("net.sf.cglib.core.Signature")) {
                        return 14;
                    }
                }
            }
            break;
        case 1543336191:
            if (var1.equals("CGLIB$toString$4")) {
                switch(var2.length) {
                case 0:
                    return 17;
                }
            }
            break;
        case 1811874389:
            if (var1.equals("newInstance")) {
                switch(var2.length) {
                case 1:
                    String var10001 = var2[0].getName();
                    switch(var10001.hashCode()) {
                    case -845341380:
                        if (var10001.equals("net.sf.cglib.proxy.Callback")) {
                            return 4;
                        }
                        break;
                    case 1730110032:
                        if (var10001.equals("[Lnet.sf.cglib.proxy.Callback;")) {
                            return 3;
                        }
                    }
                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("[Lnet.sf.cglib.proxy.Callback;")) {
                        return 5;
                    }
                }
            }
            break;
        case 1817099975:
            if (var1.equals("setCallback")) {
                switch(var2.length) {
                case 2:
                    if (var2[0].getName().equals("int") && var2[1].getName().equals("net.sf.cglib.proxy.Callback")) {
                        return 8;
                    }
                }
            }
            break;
        case 1902066072:
            if (var1.equals("notifyAll")) {
                switch(var2.length) {
                case 0:
                    return 28;
                }
            }
            break;
        case 1905679803:
            if (var1.equals("getCallback")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("int")) {
                        return 13;
                    }
                }
            }
            break;
        case 1950568386:
            if (var1.equals("getClass")) {
                switch(var2.length) {
                case 0:
                    return 26;
                }
            }
            break;
        case 1951977612:
            if (var1.equals("CGLIB$clone$6")) {
                switch(var2.length) {
                case 0:
                    return 21;
                }
            }
        }

        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 {
        2276c04 var10000 = (2276c04)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.newInstance((Callback[])var3[0]);
            case 4:
                return var10000.newInstance((Callback)var3[0]);
            case 5:
                return var10000.newInstance((Class[])var3[0], (Object[])var3[1], (Callback[])var3[2]);
            case 6:
                var10000.test();
                return null;
            case 7:
                var10000.say();
                return null;
            case 8:
                var10000.setCallback(((Number)var3[0]).intValue(), (Callback)var3[1]);
                return null;
            case 9:
                var10000.setCallbacks((Callback[])var3[0]);
                return null;
            case 10:
                2276c04.CGLIB$SET_THREAD_CALLBACKS((Callback[])var3[0]);
                return null;
            case 11:
                2276c04.CGLIB$SET_STATIC_CALLBACKS((Callback[])var3[0]);
                return null;
            case 12:
                return var10000.getCallbacks();
            case 13:
                return var10000.getCallback(((Number)var3[0]).intValue());
            case 14:
                return 2276c04.CGLIB$findMethodProxy((Signature)var3[0]);
            case 15:
                var10000.CGLIB$say$1();
                return null;
            case 16:
                var10000.CGLIB$finalize$2();
                return null;
            case 17:
                return var10000.CGLIB$toString$4();
            case 18:
                return new Integer(var10000.CGLIB$hashCode$5());
            case 19:
                return new Boolean(var10000.CGLIB$equals$3(var3[0]));
            case 20:
                var10000.CGLIB$test$0();
                return null;
            case 21:
                return var10000.CGLIB$clone$6();
            case 22:
                2276c04.CGLIB$STATICHOOK1();
                return null;
            case 23:
                var10000.wait();
                return null;
            case 24:
                var10000.wait(((Number)var3[0]).longValue(), ((Number)var3[1]).intValue());
                return null;
            case 25:
                var10000.wait(((Number)var3[0]).longValue());
                return null;
            case 26:
                return var10000.getClass();
            case 27:
                var10000.notify();
                return null;
            case 28:
                var10000.notifyAll();
                return null;
            }
        } catch (Throwable var4) {
            throw new InvocationTargetException(var4);
        }

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

    public Object newInstance(int var1, Object[] var2) throws InvocationTargetException {
        2276c04 var10000 = new 2276c04;
        2276c04 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 28;
    }
}


分别看两种fastClass的invoke方法
执行代理类

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

        try {
            switch(var10001) {
        ····················
                var10000.say();
                return null;
            case 3:
                var10000.setId(((Number)var3[0]).intValue());
                return null;
            case 4:
                var10000.setNo((String)var3[0]);
                return null;
            case 5:
                return var10000.getMoney();
            case 6:
                var10000.setMoney((BigDecimal)var3[0]);
                return null;
            case 7:
      ····················
    }

执行代理类,又会走一遍MethodInterceptor拦截器的逻辑。
执行父类的fastclass


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

        try {
            switch(var10001) {
            case 0:
    
                var10000.CGLIB$say$2();
                return null;
            case 34:
                return var10000.CGLIB$getNo$7();
            case 35:
                var10000.CGLIB$setMoney$6((BigDecimal)var3[0]);
                return null;
            case 36:
                var10000.CGLIB$setId$3(((Number)var3[0]).intValue());
                return null;
            case 37:
                var10000.CGLIB$setNo$4((String)var3[0]);
                return null;
            case 38:
                var10000.CGLIB$test$1();
                return null;
     
     

    }

这里不是直接调用方法,而是一个奇怪的方法名


    final void CGLIB$say$2() {
        super.say();
    }

代理类直接调用父类的实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/13572.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

随笔记:计算机基础及进制计数法

随笔记&#xff1a;计算机基础及进制计数法 记录一下最近接触的基本的概念&#xff0c;便于想看的时候随时来翻看一下。 基础理论还是比较重要滴&#xff0c;基础理论还是比较重要滴&#xff0c;基础理论还是比较重要滴 现代计算机是用 0 和 1 来表示信息的&#xff0c;使用的…

6、行为型模式-责任链模式

一、责任链模式描述 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;为请求创建了一个接收者对象的链。这种模式给予请求的类型&#xff0c;对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。 在这种模式中&#xff0c;通常每个接收者…

Unity AVPro 使用

AVPro 感觉我写的没多大用处&#xff0c;后面看看文档再完善一些。目前的东西是可以满足一些简单的需求的。 说明 标题名称内容Unity版本Unity 2021 .1.18f1c1AVPro 版本AVPro Video - Ultra Edition 2.5.6IDEVS2022系统版本Win 10 1909撰写日期2022 11月15日晚 需要注意的地…

防孤岛保护装置在光伏行业的应用

安科瑞 华楠 应用场景 防孤岛原理&#xff1a;防孤岛保护装置检测到并网点有逆功率、频率突变、 等异常数据时&#xff0c;即发生孤岛现象时&#xff0c;装置可配合断路器快速切除并网点&#xff0c;使本站与电网侧快速脱离&#xff0c;保证整个电站和相关维护人员的生命安全 …

Go:Signal信号量的简介与实践(优雅的退出)

文章目录简介一、kill与kill9的区别二、实践&#xff1a;优雅的退出小结简介 go中的信号量 有些信号名对应着3个信号值&#xff0c;这是因为这些信号值与平台相关&#xff0c;SIGKILL和SIGSTOP这两个信号既不能被应用程序捕获&#xff0c;也不能被操作系统阻塞或忽略。 一、…

智慧管廊解决方案-最新全套文件

智慧管廊解决方案-最新全套文件一、建设背景二、建设意义三、建设目标四、思路架构综合管廊目前存在的痛点1、安全防范不足2、管理技术落后3、信息孤岛问题4、多头管理问题五、建设方案六、获取 - 智慧管廊全套最新解决方案合集一、建设背景 综合管廊一般是建于城市地下用于容…

NUMA架构详解

基本概念 为什么要有多处理器架构&#xff1f; 由于摩尔定律的失效&#xff0c;单个CPU内的晶体管的数量接近于饱和状态&#xff0c;因此单个CPU的性能已经接近饱和状态&#xff0c;这时&#xff0c;要想提高计算机的性能&#xff0c;就必须朝着多核架构发展。多核架构中&…

力扣(leetcode)刷题分享,简单题(第2期)

力扣第二期介绍1. 反转链表2. 移除链表元素3. 找链表的中间节点4. 寻找链表中的倒数第k个结点5. 合并两个有序链表总结第二期介绍 本期博客主要讲解的题目是有关链表的一些经典OJ题&#xff0c;有一定难度&#xff0c;希望大家耐心看完。 1. 反转链表 题目介绍&#xff1a; …

VUE Date类型前端判断动态校验

需求 原本需求 一个编号和一个日期在流程中的审查人节点必填&#xff0c;于是我就直接写了前端必填校验 所有代码和名称已做更改&#xff0c;不涉及到公司隐私 <CustomFormItem label"登记编号" prop"registerNo" v-if"asset_examiner form.node …

cleanmymac2023免费版纯净mac电脑系统管家

如今&#xff0c;我们在生活的方方面面都使用支持互联网的设备——查找信息、购物、银行、做作业、玩游戏&#xff0c;以及与朋友和家人保持联系。因此&#xff0c;我们的设备包含许多关于我们的个人信息。 此外&#xff0c;随着时间的推移&#xff0c;任何伟大的设备都会变得…

VIAVI唯亚威FFL-050/-100 可视故障定位仪

不管是进行安装还是故障排查&#xff0c;可视故障定位仪 (VFL) 都是快速、 方便定位光纤问题区域的必要工具。通过显示光纤损坏的准确位置&#xff0c; 技术人员能诊断、定位并有效地修复故障点。VFL 也可用于执行连接 性测试和光纤识别。 用于检查光纤弯曲和断裂、损伤位置和…

iNFTnews|Facebook、Twitter先后扑街,社交媒体的未来属于Web3?

最近埃隆马斯克&#xff08;Elon Musk&#xff09;收购推特的举动引发了热议。一方面&#xff0c;一些用户认为这位特立独行、做事说一不二的亿万富翁可以真正充分发挥平台的巨大潜力。但另外一部分人却因此担忧互联网未来的发展。 想想看&#xff0c;推特是世界上用户最多的社…

javaweb之会话技术

Cookie Cookie的基本使用 对于Cookie的使用&#xff0c;我们更关注的应该是后台代码如何操作Cookie&#xff0c;对于Cookie的操作主要分两大类&#xff0c;本别是发送Cookie和获取Cookie,对于上面这两块内容。 1、发送Cookie 创建Cookie对象&#xff0c;并设置数据 Cookie c…

6-1 邻接矩阵存储图的深度优先遍历

6-1 邻接矩阵存储图的深度优先遍历 分数 20 作者 DS课程组 单位 浙江大学 试实现邻接矩阵存储图的深度优先遍历。 函数接口定义&#xff1a; void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) );其中MGraph是邻接矩阵存储的图&#xff0c;定义如下&#xff1a; t…

35岁互联网人只会被清退,是我听过最大的谎言

作为一个在测试行业摸爬滚打11年的老鸟&#xff0c;距离35岁还有两个月&#xff0c;目前在一家互联网公司担任 测试总监 的岗位。回看这些年的进阶之路&#xff0c;能做到今天的职位&#xff0c;关键的就是那几步。 而我认识的目前已失业和依然在做基层测试的同行&#xff0c;…

谷歌插件使用开发

谷歌插件 谷歌浏览器扩展程序&#xff1a;扩展是 Web 平台中使用的HTML、CSS、JavaScript、图像和其他文件的压缩包。可以修改用户浏览并与之交互中的web内容&#xff0c;它们还可以扩展和更改浏览器本身的行为。 开发核心 api 文档&#xff1a;link 插件主要是根据包内的mani…

mysql数据库主从同步

数据库版本 主&#xff1a;5.7.34 从&#xff1a;8.0.21 主数据库 修改mysql配置文件 my.ini&#xff08;windows&#xff09; 查看配置文件存在位置 -- 查看配置文件存在位置 show variables like %data%;修改内容 boo_db为同步的数据库名 server-id1log-binmysql-bin#目标…

手写一个单例模式,Demo,检测

手写一个单例模式&#xff0c;Demo&#xff0c;检测需求分析单例介绍一般情况DemoResult单例模式&#xff08;饿汉式—静态常量方式&#xff08;线程安全&#xff09;&#xff09;DemoResult懒汉式&#xff08;线程不安全&#xff09;DemoResult懒汉式&#xff08;加入锁机制&a…

K8s安装乐维5.0应用部署文档

乐维产品包具体打包为4个镜像包&#xff0c;分别为&#xff1a;mysql5.7.36.tar、zabbix_server.tar、itops_v1_4_x86_64.tar、bpm0.1.tar&#xff0c;对应的配置文件分别为&#xff1a;data.tar、conf.tar、nginx-v1.3.tar.gz、bpm12.zip。 K8s yaml文件具体打包为strogeclas…

[附源码]Python计算机毕业设计django学生学习评价与分析系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…