【java基础】代理

代理


1 概念

代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象。这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。

功能增强、访问控制


2 类别

2.1 静态代理

​ 实现目标的接口或者直接继承目标类,完成逻辑的修改


2.2 动态代理

2.2.1 JDK动态代理
2.2.1.1 使用
/**
 * @Description 被代理类接口
 * @Author czc
 * @Date 2023/6/4 16:39
 */
public interface ITagService {
    /**
     * 保存
     * @param name
     */
    void save(String name);

    /**
     * 获取
     * @return
     */
    String get();
}
/**
 * @Description 被代理类
 * @Author czc
 * @Date 2023/6/4 16:45
 */
public class TagServiceImpl implements ITagService {
    @Override
    public void save(String name) {
        System.out.println(String.format("保存名字为【%s】", name));
    }

    @Override
    public String get() {
        System.out.println("获取名字为【czc】");
        return "czc";
    }
}
/**
 * @Description 增强类
 * @Author czc
 * @Date 2023/6/4 17:02
 */
public abstract class AbstractTransaction {

    public void before() {
        System.out.println("执行前操作");
    }

    public void after() {
        System.out.println("执行后操作");
    }

    public void error() {
        System.out.println("异常后操作");
    }
}

InvocationHandler接口是proxy代理实例的调用处理程序实现的一个接口,每一个proxy代理实例都有一个关联的调用处理程序;在代理实例调用方法时,方法调用被编码分派到调用处理程序的invoke方法。

/**
 * @Description 处理器
 * @Author czc
 * @Date 2023/6/4 16:51
 */
public class JdkInvocation<T> implements InvocationHandler {

    private AbstractTransaction transaction;
    /**
     * 被代理对象
     */
    private T target;

    public JdkInvocation(AbstractTransaction transaction, T target) {
        this.transaction = transaction;
        this.target = target;
    }

    /**
     * proxy:代表动态代理对象
     * method:目标执行方法(正在执行)
     * args:目标方法参数
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try {
            transaction.before();
            Object result = method.invoke(target, args);
            transaction.after();
            return result;
        }catch (Exception e) {
            transaction.error();
            throw e;
        }
    }
}
/**
 * @Description 测试类
 * @Author czc
 * @Date 2023/6/4 17:33
 */
public class JdkProxyTest {

    @Test
    public void test() {
        // 指定增强类
        AbstractTransaction transaction = new ProxyTransaction();

        // 指定被代理类
        ITagService service = new TagServiceImpl();

        // 拦截处理器
        JdkInvocation invocation = new JdkInvocation(transaction, service);

        ITagService o = (ITagService) Proxy.newProxyInstance(TagServiceImpl.class.getClassLoader(), TagServiceImpl.class.getInterfaces(), invocation);
        o.save("czc");
        o.get();

        this.saveProxyClass("E:\\project\\demo\\jdk-proxy\\target");
    }

    /**
     * 生成代理类字节码文件
     * @param path
     */
    private void saveProxyClass(String path) {
        byte[] $proxy0s = ProxyGenerator.generateProxyClass("$Proxy0", TagServiceImpl.class.getInterfaces());

        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(new File(path + "$Proxy0.class"));
            fos.write($proxy0s);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
2.2.1.2 源码解析
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException {
    Objects.requireNonNull(h);

    final Class<?>[] intfs = interfaces.clone();
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
    }

    /*
     * Look up or generate the designated proxy class.
     */
     // 1、生成代理类
    Class<?> cl = getProxyClass0(loader, intfs);

    /*
     * Invoke its constructor with the designated invocation handler.
     */
    try {
        if (sm != null) {
            checkNewProxyPermission(Reflection.getCallerClass(), cl);
        }
        // 2、获取参数类型是InvocationHandler的构造方法
        final Constructor<?> cons = cl.getConstructor(constructorParams);
        final InvocationHandler ih = h;
        if (!Modifier.isPublic(cl.getModifiers())) {
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {
                    cons.setAccessible(true);
                    return null;
                }
            });
        }
        // 3、使用实例化代理类
        return cons.newInstance(new Object[]{h});
    } catch (IllegalAccessException|InstantiationException e) {
        throw new InternalError(e.toString(), e);
    } catch (InvocationTargetException e) {
        Throwable t = e.getCause();
        if (t instanceof RuntimeException) {
            throw (RuntimeException) t;
        } else {
            throw new InternalError(t.toString(), t);
        }
    } catch (NoSuchMethodException e) {
        throw new InternalError(e.toString(), e);
    }
}

生成代理类

/**
 * a cache of proxy classes
 */
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
    proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) {
     if (interfaces.length > 65535) {
         throw new IllegalArgumentException("interface limit exceeded");
     }

     // If the proxy class defined by the given loader implementing
     // the given interfaces exists, this will simply return the cached copy;
     // otherwise, it will create the proxy class via the ProxyClassFactory
     return proxyClassCache.get(loader, interfaces);
 }

Proxy.ProxyClassFactory ( 创建代理类)

private static final class ProxyClassFactory implements BiFunction<ClassLoader, Class<?>[], Class<?>> {
    // prefix for all proxy class names
    private static final String proxyClassNamePrefix = "$Proxy";

    // next number to use for generation of unique proxy class names
    private static final AtomicLong nextUniqueNumber = new AtomicLong();

    @Override
    public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {

        Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
        for (Class<?> intf : interfaces) {
            /*
             * Verify that the class loader resolves the name of this
             * interface to the same Class object.
             */
            Class<?> interfaceClass = null;
            try {
                interfaceClass = Class.forName(intf.getName(), false, loader);
            } catch (ClassNotFoundException e) {
            }
            if (interfaceClass != intf) {
                throw new IllegalArgumentException(
                    intf + " is not visible from class loader");
            }
            /*
             * Verify that the Class object actually represents an
             * interface.
             */
            if (!interfaceClass.isInterface()) {
                throw new IllegalArgumentException(
                    interfaceClass.getName() + " is not an interface");
            }
            /*
             * Verify that this interface is not a duplicate.
             */
            if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
                throw new IllegalArgumentException(
                    "repeated interface: " + interfaceClass.getName());
            }
        }

        String proxyPkg = null;     // package to define proxy class in
        int accessFlags = Modifier.PUBLIC | Modifier.FINAL;

        /*
         * Record the package of a non-public proxy interface so that the
         * proxy class will be defined in the same package.  Verify that
         * all non-public proxy interfaces are in the same package.
         */
        for (Class<?> intf : interfaces) {
            int flags = intf.getModifiers();
            if (!Modifier.isPublic(flags)) {
                accessFlags = Modifier.FINAL;
                String name = intf.getName();
                int n = name.lastIndexOf('.');
                String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
                if (proxyPkg == null) {
                    proxyPkg = pkg;
                } else if (!pkg.equals(proxyPkg)) {
                    throw new IllegalArgumentException(
                        "non-public interfaces from different packages");
                }
            }
        }

        if (proxyPkg == null) {
            // if no non-public proxy interfaces, use com.sun.proxy package
            proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
        }

        /*
         * Choose a name for the proxy class to generate.
         */
        long num = nextUniqueNumber.getAndIncrement();
        String proxyName = proxyPkg + proxyClassNamePrefix + num;

        /*
         * Generate the specified proxy class.
         */
         // 重点:生成代理类
        byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);
        try {
            return defineClass0(loader, proxyName,
                                proxyClassFile, 0, proxyClassFile.length);
        } catch (ClassFormatError e) {
            /*
             * A ClassFormatError here means that (barring bugs in the
             * proxy class generation code) there was some other
             * invalid aspect of the arguments supplied to the proxy
             * class creation (such as virtual machine limitations
             * exceeded).
             */
            throw new IllegalArgumentException(e.toString());
        }
    }
}

ProxyGenerator#generateProxyClass(final String var0, Class<?>[] var1, int var2)

public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2) {
    ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);
    // 生成代理类字节码
    final byte[] var4 = var3.generateClassFile();
    if (saveGeneratedFiles) {
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            public Void run() {
                try {
                    int var1 = var0.lastIndexOf(46);
                    Path var2;
                    if (var1 > 0) {
                        Path var3 = Paths.get(var0.substring(0, var1).replace('.', File.separatorChar));
                        Files.createDirectories(var3);
                        var2 = var3.resolve(var0.substring(var1 + 1, var0.length()) + ".class");
                    } else {
                        var2 = Paths.get(var0 + ".class");
                    }

                    Files.write(var2, var4, new OpenOption[0]);
                    return null;
                } catch (IOException var4x) {
                    throw new InternalError("I/O exception saving generated file: " + var4x);
                }
            }
        });
    }

    return var4;
}

ProxyGenerator#generateClassFile()
ProxyGenerator类的generateProxyClass()静态方法的核心内容就是去调用generateClassFile()实例方法来生成Class文件。

/**
 * @link: https://blog.csdn.net/qq_32077121/article/details/108302207
 * 第一步:收集所有要生成的代理方法,将其包装成ProxyMethod对象并注册到Map集合中。
 * 第二步:收集所有要为Class文件生成的字段信息和方法信息。
 * 	1.为代理类生成一个带参构造器,传入InvocationHandler实例的引用并调用父类的带参构造器。
 *	2.遍历代理方法Map集合,为每个代理方法生成对应的Method类型静态域,并将其添加到fields集合中。
 *	3.遍历代理方法Map集合,为每个代理方法生成对应的MethodInfo对象,并将其添加到methods集合中。
 *	4.为代理类生成静态初始化方法,该静态初始化方法主要是将每个代理方法的引用赋值给对应的静态字段。
 * 第三步:完成了上面的工作后,开始组装Class文件。
 */
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();
}

测试类生成的代理类文件

/**
 * @Description 生成的代理类
 */
public final class $Proxy0 extends Proxy implements ITagService {
    //第一步, 生成构造器
    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }
    
    //第二步, 生成静态域
    private static Method m1;
    private static Method m4;
    private static Method m2;
    private static Method m3;
    private static Method m0;

    //第三步, 生成代理方法
    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 save(String var1) throws  {
        try {
            super.h.invoke(this, m4, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    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 String get() throws  {
        try {
            return (String)super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

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

    //第四步, 生成静态初始化方法
    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m4 = Class.forName("com.czc.service.ITagService").getMethod("save", Class.forName("java.lang.String"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("com.czc.service.ITagService").getMethod("get");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}
2.2.1.3 代理过程

java生成一个代理类(字节码),保存在内存中——》通过反射获取这个类中参数类型为InvocationHandler的构造方法,并创建该代理类实例对象——》调用InvocationHandler中的invoke()方法——》InvocationHandler中的invoke()方法进行增强,同时通过反射方式(invoke方法)调用被代理类的方法。

代理类是通过Proxy类的ProxyClassFactory工厂生成的,这个工厂类会去调用ProxyGenerator类的generateProxyClass()方法来生成代理类的字节码。该类的generateProxyClass()静态方法的核心内容就是去调用generateClassFile()实例方法来生成Class文件。

2.2.1.4 问
  • 为何jdk代理需要实现顶级接口?
    动态代理类的使用效果必须与被动态代理类的使用效果相同,所以必须与被动态代理类一样继承同样的类或者实现同样的接口;
    由字节码反编译出来的代理类可知,该类已经默认继承了Proxy类,java仅支持单继承,无法再继承其他类,所以只能通过实现与被代理类相同的接口,来反推出你需要代理的类的方法。
  • 为何jdk代理需要继承Proxy类
2.2.2 CGLIB代理
2.2.2.1 使用(CGLIB可直接代理接口或者类):
/**
 * @Description 被代理类接口
 * @Author czc
 * @Date 2023/6/4 16:39
 */
public interface ITagService {
    /**
     * 保存
     * @param name
     */
    void save(String name);

    /**
     * 获取
     * @return
     */
    String get();
}

/**
 * @Description 被代理类
 * @Author czc
 * @Date 2023/6/4 16:45
 */
public class TagServiceImpl implements ITagService {
    @Override
    public void save(String name) {
        System.out.println(String.format("保存名字为【%s】", name));
    }

    @Override
    public String get() {
        System.out.println("获取名字为【czc】");
        return "czc";
    }
}
/**
 * @Description 增强类
 * @Author czc
 * @Date 2023/6/4 17:02
 */
public abstract class AbstractTransaction {

    public void before() {
        System.out.println("执行前操作");
    }

    public void after() {
        System.out.println("执行后操作");
    }

    public void error() {
        System.out.println("异常后操作");
    }
}
/**
 * @Description 拦截器
 * @Author czc
 * @Date 2023/6/4 22:10
 */
public class CglibInterceptor implements MethodInterceptor {

    private AbstractTransaction transaction;

    public CglibInterceptor(AbstractTransaction transaction) {
        this.transaction = transaction;
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        transaction.before();
        Object ret = methodProxy.invokeSuper(o, objects);
        transaction.after();
        return ret;
    }
}
/**
 * @Description 测试类
 * @Author czc
 * @Date 2023/6/4 17:33
 */
public class CglibProxyTest {

    @Test
    public void test() {
        // 生成代理类
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/E:/project/demo/cglib-proxy/target/debugging/");

        // 指定增强类
        AbstractTransaction transaction = new ProxyTransaction();

        // 拦截处理器
        CglibInterceptor interceptor = new CglibInterceptor(transaction);

        // 使用CGLIB框架生成目标类的子类实现增强
        Enhancer enhancer = new Enhancer();
        // 设置父类字节码
        enhancer.setSuperclass(TagServiceImpl.class);
        // 设置拦截处理
        enhancer.setCallback(interceptor);
        TagServiceImpl service = (TagServiceImpl)enhancer.create();
        service.save("czc");
    }
}
2.2.2.2 源码解析:

// todo Enhancer生成代理类
代理类——继承了被代理类,并重写了被代理类的方法

/**
 * @Description 代理类
 */
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.czc.service.impl;

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 TagServiceImpl$$EnhancerByCGLIB$$b0956cf0 extends TagServiceImpl 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$get$0$Method; // 被代理类中的方法(父类)
    private static final MethodProxy CGLIB$get$0$Proxy; // 代理类中的方法(子类)
    private static final Object[] CGLIB$emptyArgs;
    private static final Method CGLIB$save$1$Method;
    private static final MethodProxy CGLIB$save$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("com.czc.service.impl.TagServiceImpl$$EnhancerByCGLIB$$b0956cf0");
        Class var1;
        Method[] var10000 = ReflectUtils.findMethods(new String[]{"get", "()Ljava/lang/String;", "save", "(Ljava/lang/String;)V"}, (var1 = Class.forName("com.czc.service.impl.TagServiceImpl")).getDeclaredMethods());
        CGLIB$get$0$Method = var10000[0];
        CGLIB$get$0$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "get", "CGLIB$get$0");
        CGLIB$save$1$Method = var10000[1];
        CGLIB$save$1$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/String;)V", "save", "CGLIB$save$1");
        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");
    }

    final String CGLIB$get$0() {
        return super.get();
    }

    public final String get() {
        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$get$0$Method, CGLIB$emptyArgs, CGLIB$get$0$Proxy) : super.get();
    }

    final void CGLIB$save$1(String var1) {
        super.save(var1);
    }

    public final void save(String 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) {
            var10000.intercept(this, CGLIB$save$1$Method, new Object[]{var1}, CGLIB$save$1$Proxy);
        } else {
            super.save(var1);
        }
    }

    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 -826494814:
            if (var10000.equals("save(Ljava/lang/String;)V")) {
                return CGLIB$save$1$Proxy;
            }
            break;
        case -508378822:
            if (var10000.equals("clone()Ljava/lang/Object;")) {
                return CGLIB$clone$6$Proxy;
            }
            break;
        case 366320161:
            if (var10000.equals("get()Ljava/lang/String;")) {
                return CGLIB$get$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 TagServiceImpl$$EnhancerByCGLIB$$b0956cf0() {
        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) {
        TagServiceImpl$$EnhancerByCGLIB$$b0956cf0 var1 = (TagServiceImpl$$EnhancerByCGLIB$$b0956cf0)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);
        TagServiceImpl$$EnhancerByCGLIB$$b0956cf0 var10000 = new TagServiceImpl$$EnhancerByCGLIB$$b0956cf0();
        CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
        return var10000;
    }

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

    public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
        CGLIB$SET_THREAD_CALLBACKS(var3);
        TagServiceImpl$$EnhancerByCGLIB$$b0956cf0 var10000 = new TagServiceImpl$$EnhancerByCGLIB$$b0956cf0;
        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(FastClass并不是跟代理类一块生成的,而是在第一次执行MethodProxy的invoke/invokeSuper时生成的并放在了缓存中)

public Object invoke(Object obj, Object[] args) throws Throwable {
    try {
        this.init();
        MethodProxy.FastClassInfo fci = this.fastClassInfo;
        // 调用被代理类FastClass的invoke(重点)
        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;
        }
    }
}
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
    try {
        this.init();
        MethodProxy.FastClassInfo fci = this.fastClassInfo;
        // 调用代理类FastClass的invoke(重点)
        return fci.f2.invoke(fci.i2, obj, args);
    } catch (InvocationTargetException var4) {
        throw var4.getTargetException();
    }
}

init()生成FastClass

private static class FastClassInfo {
    // 被代理类FastClass
    FastClass f1;
    // 代理类FastClass
    FastClass f2;
    // 被代理类的方法签名(index)
    int i1;
    // 代理类的方法签名
    int i2;
    private FastClassInfo() {
    }
}

private void init() {
    if (this.fastClassInfo == null) {
        synchronized(this.initLock) {
            if (this.fastClassInfo == null) {
                MethodProxy.CreateInfo ci = this.createInfo;
                MethodProxy.FastClassInfo fci = new MethodProxy.FastClassInfo();
                // 如果缓存中有就取出,没有就生成新的FastClass
                fci.f1 = helper(ci, ci.c1);
                fci.f2 = helper(ci, ci.c2);
                // 获取方法的index
                fci.i1 = fci.f1.getIndex(this.sig1);
                fci.i2 = fci.f2.getIndex(this.sig2);
                this.fastClassInfo = fci;
                this.createInfo = null;
            }
        }
    }
}

被代理类的FastClass

/**
 * @Description 被代理类的FastClass
 */
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.czc.service.impl;

import java.lang.reflect.InvocationTargetException;
import net.sf.cglib.core.Signature;
import net.sf.cglib.reflect.FastClass;

public class TagServiceImpl$$FastClassByCGLIB$$b361bee1 extends FastClass {
    public TagServiceImpl$$FastClassByCGLIB$$b361bee1(Class var1) {
        super(var1);
    }

    public int getIndex(Signature var1) {
        String var10000 = var1.toString();
        switch(var10000.hashCode()) {
        case -1725733088:
            if (var10000.equals("getClass()Ljava/lang/Class;")) {
                return 8;
            }
            break;
        case -1026001249:
            if (var10000.equals("wait(JI)V")) {
                return 3;
            }
            break;
        case -826494814:
            if (var10000.equals("save(Ljava/lang/String;)V")) {
                return 1;
            }
            break;
        case 243996900:
            if (var10000.equals("wait(J)V")) {
                return 4;
            }
            break;
        case 366320161:
            if (var10000.equals("get()Ljava/lang/String;")) {
                return 0;
            }
            break;
        case 946854621:
            if (var10000.equals("notifyAll()V")) {
                return 10;
            }
            break;
        case 1116248544:
            if (var10000.equals("wait()V")) {
                return 2;
            }
            break;
        case 1826985398:
            if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
                return 5;
            }
            break;
        case 1902039948:
            if (var10000.equals("notify()V")) {
                return 9;
            }
            break;
        case 1913648695:
            if (var10000.equals("toString()Ljava/lang/String;")) {
                return 6;
            }
            break;
        case 1984935277:
            if (var10000.equals("hashCode()I")) {
                return 7;
            }
        }

        return -1;
    }

    public int getIndex(String var1, Class[] var2) {
        switch(var1.hashCode()) {
        case -1776922004:
            if (var1.equals("toString")) {
                switch(var2.length) {
                case 0:
                    return 6;
                }
            }
            break;
        case -1295482945:
            if (var1.equals("equals")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.Object")) {
                        return 5;
                    }
                }
            }
            break;
        case -1039689911:
            if (var1.equals("notify")) {
                switch(var2.length) {
                case 0:
                    return 9;
                }
            }
            break;
        case 102230:
            if (var1.equals("get")) {
                switch(var2.length) {
                case 0:
                    return 0;
                }
            }
            break;
        case 3522941:
            if (var1.equals("save")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.String")) {
                        return 1;
                    }
                }
            }
            break;
        case 3641717:
            if (var1.equals("wait")) {
                switch(var2.length) {
                case 0:
                    return 2;
                case 1:
                    if (var2[0].getName().equals("long")) {
                        return 4;
                    }
                    break;
                case 2:
                    if (var2[0].getName().equals("long") && var2[1].getName().equals("int")) {
                        return 3;
                    }
                }
            }
            break;
        case 147696667:
            if (var1.equals("hashCode")) {
                switch(var2.length) {
                case 0:
                    return 7;
                }
            }
            break;
        case 1902066072:
            if (var1.equals("notifyAll")) {
                switch(var2.length) {
                case 0:
                    return 10;
                }
            }
            break;
        case 1950568386:
            if (var1.equals("getClass")) {
                switch(var2.length) {
                case 0:
                    return 8;
                }
            }
        }

        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 {
        TagServiceImpl var10000 = (TagServiceImpl)var2;
        int var10001 = var1;

        try {
            switch(var10001) {
            case 0:
                return var10000.get();
            case 1:
                var10000.save((String)var3[0]);
                return null;
            case 2:
                var10000.wait();
                return null;
            case 3:
                var10000.wait(((Number)var3[0]).longValue(), ((Number)var3[1]).intValue());
                return null;
            case 4:
                var10000.wait(((Number)var3[0]).longValue());
                return null;
            case 5:
                return new Boolean(var10000.equals(var3[0]));
            case 6:
                return var10000.toString();
            case 7:
                return new Integer(var10000.hashCode());
            case 8:
                return var10000.getClass();
            case 9:
                var10000.notify();
                return null;
            case 10:
                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 {
        TagServiceImpl var10000 = new TagServiceImpl;
        TagServiceImpl 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 10;
    }
}

代理类的FastClass

/**
 * @Description 代理类的FastClass
 */
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.czc.service.impl;

import com.czc.service.impl.TagServiceImpl..EnhancerByCGLIB..b0956cf0;
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 TagServiceImpl$$EnhancerByCGLIB$$b0956cf0$$FastClassByCGLIB$$43f1c126 extends FastClass {
    public TagServiceImpl$$EnhancerByCGLIB$$b0956cf0$$FastClassByCGLIB$$43f1c126(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 12;
            }
            break;
        case -2055565910:
            if (var10000.equals("CGLIB$SET_THREAD_CALLBACKS([Lnet/sf/cglib/proxy/Callback;)V")) {
                return 22;
            }
            break;
        case -1754654774:
            if (var10000.equals("CGLIB$get$0()Ljava/lang/String;")) {
                return 15;
            }
            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 17;
            }
            break;
        case -1457535688:
            if (var10000.equals("CGLIB$STATICHOOK1()V")) {
                return 9;
            }
            break;
        case -1411783143:
            if (var10000.equals("CGLIB$hashCode$5()I")) {
                return 13;
            }
            break;
        case -1026001249:
            if (var10000.equals("wait(JI)V")) {
                return 24;
            }
            break;
        case -894172689:
            if (var10000.equals("newInstance(Lnet/sf/cglib/proxy/Callback;)Ljava/lang/Object;")) {
                return 6;
            }
            break;
        case -826494814:
            if (var10000.equals("save(Ljava/lang/String;)V")) {
                return 7;
            }
            break;
        case -623122092:
            if (var10000.equals("CGLIB$findMethodProxy(Lnet/sf/cglib/core/Signature;)Lnet/sf/cglib/proxy/MethodProxy;")) {
                return 10;
            }
            break;
        case -419626537:
            if (var10000.equals("setCallbacks([Lnet/sf/cglib/proxy/Callback;)V")) {
                return 19;
            }
            break;
        case 243996900:
            if (var10000.equals("wait(J)V")) {
                return 25;
            }
            break;
        case 366320161:
            if (var10000.equals("get()Ljava/lang/String;")) {
                return 0;
            }
            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 4;
            }
            break;
        case 946854621:
            if (var10000.equals("notifyAll()V")) {
                return 28;
            }
            break;
        case 973717575:
            if (var10000.equals("getCallbacks()[Lnet/sf/cglib/proxy/Callback;")) {
                return 20;
            }
            break;
        case 1116248544:
            if (var10000.equals("wait()V")) {
                return 23;
            }
            break;
        case 1178082002:
            if (var10000.equals("CGLIB$save$1(Ljava/lang/String;)V")) {
                return 14;
            }
            break;
        case 1221173700:
            if (var10000.equals("newInstance([Lnet/sf/cglib/proxy/Callback;)Ljava/lang/Object;")) {
                return 5;
            }
            break;
        case 1230699260:
            if (var10000.equals("getCallback(I)Lnet/sf/cglib/proxy/Callback;")) {
                return 18;
            }
            break;
        case 1365107430:
            if (var10000.equals("CGLIB$finalize$2()V")) {
                return 16;
            }
            break;
        case 1584330438:
            if (var10000.equals("CGLIB$SET_STATIC_CALLBACKS([Lnet/sf/cglib/proxy/Callback;)V")) {
                return 21;
            }
            break;
        case 1729170762:
            if (var10000.equals("CGLIB$toString$4()Ljava/lang/String;")) {
                return 11;
            }
            break;
        case 1826985398:
            if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
                return 1;
            }
            break;
        case 1902039948:
            if (var10000.equals("notify()V")) {
                return 27;
            }
            break;
        case 1913648695:
            if (var10000.equals("toString()Ljava/lang/String;")) {
                return 2;
            }
            break;
        case 1984935277:
            if (var10000.equals("hashCode()I")) {
                return 3;
            }
        }

        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 2;
                }
            }
            break;
        case -1295482945:
            if (var1.equals("equals")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.Object")) {
                        return 1;
                    }
                }
            }
            break;
        case -1053468136:
            if (var1.equals("getCallbacks")) {
                switch(var2.length) {
                case 0:
                    return 20;
                }
            }
            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 17;
                    }
                }
            }
            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 21;
                    }
                }
            }
            break;
        case -29025553:
            if (var1.equals("CGLIB$hashCode$5")) {
                switch(var2.length) {
                case 0:
                    return 13;
                }
            }
            break;
        case 102230:
            if (var1.equals("get")) {
                switch(var2.length) {
                case 0:
                    return 0;
                }
            }
            break;
        case 3522941:
            if (var1.equals("save")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.String")) {
                        return 7;
                    }
                }
            }
            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 22;
                    }
                }
            }
            break;
        case 147696667:
            if (var1.equals("hashCode")) {
                switch(var2.length) {
                case 0:
                    return 3;
                }
            }
            break;
        case 161998109:
            if (var1.equals("CGLIB$STATICHOOK1")) {
                switch(var2.length) {
                case 0:
                    return 9;
                }
            }
            break;
        case 495524492:
            if (var1.equals("setCallbacks")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("[Lnet.sf.cglib.proxy.Callback;")) {
                        return 19;
                    }
                }
            }
            break;
        case 511072589:
            if (var1.equals("CGLIB$save$1")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.String")) {
                        return 14;
                    }
                }
            }
            break;
        case 1113897855:
            if (var1.equals("CGLIB$get$0")) {
                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 10;
                    }
                }
            }
            break;
        case 1543336191:
            if (var1.equals("CGLIB$toString$4")) {
                switch(var2.length) {
                case 0:
                    return 11;
                }
            }
            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 6;
                        }
                        break;
                    case 1730110032:
                        if (var10001.equals("[Lnet.sf.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("[Lnet.sf.cglib.proxy.Callback;")) {
                        return 4;
                    }
                }
            }
            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 18;
                    }
                }
            }
            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 12;
                }
            }
        }

        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 {
        b0956cf0 var10000 = (b0956cf0)var2;
        int var10001 = var1;

        try {
            switch(var10001) {
            case 0:
                return var10000.get();
            case 1:
                return new Boolean(var10000.equals(var3[0]));
            case 2:
                return var10000.toString();
            case 3:
                return new Integer(var10000.hashCode());
            case 4:
                return var10000.newInstance((Class[])var3[0], (Object[])var3[1], (Callback[])var3[2]);
            case 5:
                return var10000.newInstance((Callback[])var3[0]);
            case 6:
                return var10000.newInstance((Callback)var3[0]);
            case 7:
                var10000.save((String)var3[0]);
                return null;
            case 8:
                var10000.setCallback(((Number)var3[0]).intValue(), (Callback)var3[1]);
                return null;
            case 9:
                b0956cf0.CGLIB$STATICHOOK1();
                return null;
            case 10:
                return b0956cf0.CGLIB$findMethodProxy((Signature)var3[0]);
            case 11:
                return var10000.CGLIB$toString$4();
            case 12:
                return var10000.CGLIB$clone$6();
            case 13:
                return new Integer(var10000.CGLIB$hashCode$5());
            case 14:
                var10000.CGLIB$save$1((String)var3[0]);
                return null;
            case 15:
                return var10000.CGLIB$get$0();
            case 16:
                var10000.CGLIB$finalize$2();
                return null;
            case 17:
                return new Boolean(var10000.CGLIB$equals$3(var3[0]));
            case 18:
                return var10000.getCallback(((Number)var3[0]).intValue());
            case 19:
                var10000.setCallbacks((Callback[])var3[0]);
                return null;
            case 20:
                return var10000.getCallbacks();
            case 21:
                b0956cf0.CGLIB$SET_STATIC_CALLBACKS((Callback[])var3[0]);
                return null;
            case 22:
                b0956cf0.CGLIB$SET_THREAD_CALLBACKS((Callback[])var3[0]);
                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 {
        b0956cf0 var10000 = new b0956cf0;
        b0956cf0 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;
    }
}
2.2.2.3 概念
  • 关于FastClass
    为代理类和被代理类各生成一个Class(就是上面的两个FastClass的class文件),这个Class会为代理类或被代理类的方法分配一个index(int类型)。 这个index当做一个入参,FastClass就可以直接定位要调用的方法直接进行调用,这样省去了反射调用,所以调用效率比JDK动态代理通过反射调用高。
2.2.2.4 问:
  • MethodProxy中invoke与invokeSuper的相同与区别
    同:都生成了FastClass类,也都会调用各自FastClass的invoke方法。
    不同:
    invoke调用被代理类FastClass的invoke,而invokeSuper调用代理类FastClass的invoke。

  • MethodProxy使用method.invoke(o, objects)为何会导致死循环,如何破解?
    导致死循环:生成代理对象后,调用代理对象的a方法,此时进入拦截类里面,然后你又通过反射去调用代理类的a方法,套娃形成
    破解:invoke()参数中直接传被代理对象的class(即直接调用被代理对象的方法)可跳出循环。


感谢csdn相关文章博主以及b站相关视频up,源于学习过程中的记录。
持续补充中。。。。。。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值