动态代理实现源码剖析 —— 深入分析cglib动态代理

cglib 动态代理

前言

cglib的源码实现要比JDK动态代理复杂的多,刚开始看会觉得很绕,其实只要把握住主线,明白总体的设计思路,看起来就会比较流程。

总体思路:整个过程就是围绕着AbstractClassGenerator和其子类进行。

  1. AbstractClassGenerator作为整个代理类的核心类,完成代理类对象实例的创建。
  2. 代理类本身的类创建动作由不同的AbstractClassGenerator子类来完成。
  3. cglib通过给原始类和代理类的所有方法标记索引值,达到避免反射调用的目的。

基本用法

public class CGLibProxy {

    private Class clazz;

    public CGLibProxy(Class clazz) {
        this.clazz = clazz;
    }

    static  {
        // 用于输出生产代理类,源码查看用
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, ".");
    }

    public Object proxy() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(new CustomCallback());
        Object o = enhancer.create();
        return o;
    }

    public static void main(String[] args) {
        SomeClass proxy = (SomeClass)new CGLibProxy(SomeClass.class).proxy();
        proxy.doSomething();
    }
}

class SomeClass {

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

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

class CustomCallback implements MethodInterceptor {

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("增强");
        Object invoke = methodProxy.invokeSuper(obj, args);
        return invoke;
    }
}
  1. 创建Enhancer对象
  2. 设置要扩展的类对象作为代理类的父类
  3. 设置回调类
  4. 回调类实现MethodInterceptor 扩展原方法功能

扩展用法

        enhancer.setCallbacks(new Callback[] {new CustomCallback(), new CustomCallback2()});
        enhancer.setCallbackFilter(new CustomCallbackFilter());

public class CustomCallbackFilter implements CallbackFilter {

    @Override
    public int accept(Method method) {
        if (method.getName().contains("doSomething")) {
            return 0;
        } else if(method.getName().contains("doOtherthing")) {
            return 1;
        }
        return 0;
    }
}

设置回调过滤器,动态设置哪个方法用哪个Callback类的实现进行回调。

源码分析

Enhancer构造过程

        Enhancer enhancer = new Enhancer();

cglib在初始化时就做了很多事情。
首先是Enhancer的构造过程:

public class Enhancer extends AbstractClassGenerator {
    //定义默认的CallbackFilter, 且accept都设置为0
    private static final CallbackFilter ALL_ZERO = new CallbackFilter(){
        public int accept(Method method) {
            return 0;
        }
    };

    private static final Source SOURCE = new Source(Enhancer.class.getName());
    // 这里构造了一个EnhancerKey,内部会生成cglib的一个代理类
    // net.sf.cglib.proxy.Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72  详情见附录
    private static final EnhancerKey KEY_FACTORY =
      (EnhancerKey)KeyFactory.create(EnhancerKey.class, KeyFactory.HASH_ASM_TYPE, null);

KEY_FACTORY创建过程

先看下KEY_FACTORY的创建过程:

 public static KeyFactory create(ClassLoader loader, Class keyInterface, KeyFactoryCustomizer customizer, List next) {
        Generator gen = new Generator();
        gen.setInterface(keyInterface);

        if (customizer != null) {
            gen.addCustomizer(customizer);
        }
        if (next != null && !next.isEmpty()) {
            for (KeyFactoryCustomizer keyFactoryCustomizer : next) {
                gen.addCustomizer(keyFactoryCustomizer);
            }
        }
        gen.setClassLoader(loader);
        return gen.create();
    }

keyInterface是EnhancerKey.class, 设置类加载是keyInterface的classloader。最后调用gen.create()开始创建并加载这个Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72

public static class Generator extends AbstractClassGenerator {
    // ...
    public KeyFactory create() {
            setNamePrefix(keyInterface.getName());
            return (KeyFactory)super.create(keyInterface.getName());
        }

这里的namePrefix就是net.sf.cglib.proxy.Enhancer$EnhancerKey
super.create是父类AbstractClassGenerator的实现。

abstract public class AbstractClassGenerator implements ClassGenerator {
    // ...
    protected Object create(Object key) {
        try {
            ClassLoader loader = getClassLoader();
            Map cache = CACHE;
            ClassLoaderData data = cache.get(loader);
            if (data == null) {
                synchronized (AbstractClassGenerator.class) {
                    cache = CACHE;
                    data = cache.get(loader);
                    if (data == null) {
                        Map newCache = new WeakHashMap(cache);
                        data = new ClassLoaderData(loader);
                        newCache.put(loader, data);
                        CACHE = newCache;
                    }
                }
            }
            this.key = key;
            Object obj = data.get(this, getUseCache());
            if (obj instanceof Class) {
                return firstInstance((Class) obj);
            }
            return nextInstance(obj);
        } catch (RuntimeException e) {
            throw e;
        } catch (Error e) {
            throw e;
        } catch (Exception e) {
            throw new CodeGenerationException(e);
        }
    }

    protected static class ClassLoaderData {

         public ClassLoaderData(ClassLoader classLoader) {
            if (classLoader == null) {
                throw new IllegalArgumentException("classLoader == null is not yet supported");
            }
            this.classLoader = new WeakReference(classLoader);
            Function load =
                    new Function() {
                        public Object apply(AbstractClassGenerator gen) {
                            Class klass = gen.generate(ClassLoaderData.this);
                            return gen.wrapCachedClass(klass);
                        }
                    };
            generatedClasses = new LoadingCache(GET_KEY, load);
        }

       private static final Function GET_KEY = new Function() {
            public Object apply(AbstractClassGenerator gen) {
                return gen.key;
            }
        };

第一部分是构造全局的Map CACHE,并创建第一个new ClassLoaderData(loader);
ClassLoaderData的构造方法定义了Function的load,并初始化了全局的generatedClasses。

第二部分就是通过data来生成代理类,入口是data.get(this, getUserCache()); 这里的catch默认是true。

      public Object get(AbstractClassGenerator gen, boolean useCache) {
            if (!useCache) {
              return gen.generate(ClassLoaderData.this);
            } else {
              Object cachedValue = generatedClasses.get(gen);
              return gen.unwrapCachedValue(cachedValue);
            }
        }

重点就是代理类的生成过程,由generatedClasses生成代理类class对象。


    private static final Function GET_KEY = new Function() {
            public Object apply(AbstractClassGenerator gen) {
                // 这里的key是String类型的"net.sf.cglib.proxy.Enhancer$EnhancerKey"
                return gen.key;
            }
        };

第一次缓存不存在,会调用createEntry。

protected V createEntry(final K key, KK cacheKey, Object v) {
        FutureTask task;
        boolean creator = false;
        if (v != null) {
            // Another thread is already loading an instance
            task = (FutureTask) v;
        } else {
            task = new FutureTask(new Callable() {
                public V call() throws Exception {
                    return loader.apply(key);
                }
            });
            Object prevTask = map.putIfAbsent(cacheKey, task);
            if (prevTask == null) {
                // creator does the load
                creator = true;
                task.run();
            } else if (prevTask instanceof FutureTask) {
                task = (FutureTask) prevTask;
            } else {
                return (V) prevTask;
            }
        }

        V result;
        try {
            result = task.get();
        } catch (InterruptedException e) {
            ...
        }
        if (creator) {
            map.put(cacheKey, result);
        }
        return result;
    }

这里最主要的call方法的调用,loader是

最终会调用到构造generatedClasses的load的Function的apply。

AbstractClassGenerator.generate

    protected Class generate(ClassLoaderData data) {
        Class gen;
        Object save = CURRENT.get();
        CURRENT.set(this);
        try {
            ClassLoader classLoader = data.getClassLoader();
            if (classLoader == null) {
                throw new IllegalStateException("ClassLoader is null while trying to define class " +
                        getClassName() + ". It seems that the loader has been expired from a weak reference somehow. " +
                        "Please file an issue at cglib's issue tracker.");
            }
            synchronized (classLoader) {
              // 这一行就是起类名
              String name = generateClassName(data.getUniqueNamePredicate());              
              data.reserveName(name);
              this.setClassName(name);
            }
            if (attemptLoad) {
                try {
                    gen = classLoader.loadClass(getClassName());
                    return gen;
                } catch (ClassNotFoundException e) {
                    // ignore
                }
            }
            byte[] b = strategy.generate(this);
            String className = ClassNameReader.getClassName(new ClassReader(b));
            ProtectionDomain protectionDomain = getProtectionDomain();
            synchronized (classLoader) { // just in case
                if (protectionDomain == null) {
                    gen = ReflectUtils.defineClass(className, b, classLoader);
                } else {
                    gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain);
                }
            }
            return gen;
        } catch (RuntimeException e) {
            throw e;
        } catch (Error e) {
            throw e;
        } catch (Exception e) {
            throw new CodeGenerationException(e);
        } finally {
            CURRENT.set(save);
        }
    }

这一段就是真正在完成各种代理类的构造过程,比如此时就是在生成net.sf.cglib.proxy.Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72这个代理类

  1. 给代理类起名字
  2. 由不同的子类完成代理类的内容定义
  3. 类加载器load到jvm中

String name = generateClassName(data.getUniqueNamePredicate());
先给类起名字:三部分的拼接。

public String getClassName(String prefix, String source, Object key, Predicate names) {
        if (prefix == null) {
            prefix = "net.sf.cglib.empty.Object";
        } else if (prefix.startsWith("java")) {
            prefix = "$" + prefix;
        }
        String base =
            prefix + "$$" + 
            source.substring(source.lastIndexOf('.') + 1) +
            getTag() + "$$" +
            Integer.toHexString(STRESS_HASH_CODE ? 0 : key.hashCode());
        String attempt = base;
        int index = 2;
        while (names.evaluate(attempt))
            attempt = base + "_" + index++;
        return attempt;
    }

byte[] b = strategy.generate(this); 这里的this是KeyFactory$Generator

public byte[] generate(ClassGenerator cg) throws Exception {
        DebuggingClassWriter cw = getClassVisitor();
        transform(cg).generateClass(cw);
        return transform(cw.toByteArray());
    }

按照默认的生成策略生成字节码,主要是利用ASM来生成字节码,内部用DebuggingClassWriter封装了一下,提供了可以输出字节码文件位置的扩展。本质还是通过ClassWriter来生成。最后返回字节码的字节数组。

其中,不同实现类的具体实现规则,由cg.generateClass(cw); 来完成。
下图可以看到很多的具体类型有不同字节码实现。


image.png

gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain);
通过反射调用类加载的defineClass方法来加载这个代理类。

public static Class defineClass(String className, byte[] b, ClassLoader loader, ProtectionDomain protectionDomain) throws Exception {
        Class c;
        if (DEFINE_CLASS != null) {
            Object[] args = new Object[]{className, b, new Integer(0), new Integer(b.length), protectionDomain };
            c = (Class)DEFINE_CLASS.invoke(loader, args);
        } else if (DEFINE_CLASS_UNSAFE != null) {
            Object[] args = new Object[]{className, b, new Integer(0), new Integer(b.length), loader, protectionDomain };
            c = (Class)DEFINE_CLASS_UNSAFE.invoke(UNSAFE, args);
        } else {
            throw new CodeGenerationException(THROWABLE);
        }
        // Force static initializers to run.
        Class.forName(className, true, loader);
        return c;
    }

最后返回代理类的class对象。



在上层会将这个代理类保证成WeakReference返回,并保存到LoadingCache的全局map中。key是字符串net.sf.cglib.proxy.Enhancer$EnhancerKey。

回到最上层的create方法,

          Object obj = data.get(this, getUseCache());
            if (obj instanceof Class) {
                return firstInstance((Class) obj);
            }

obj就是net.sf.cglib.proxy.Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72的class对象
调用firstInstance 创建实例对象,作为KEY_FACTORY。

至此,KEY_FACTORY 创建过程分析完成。
其他是定义各种的Type,将各种java语法和关键词转成ASM中的Type,用于后续的代理类定义。

Enhancer的构造方法主要完成的上述事情。

回调赋值

  1. 设置要扩展的原始类
  2. 设置回调的callback类,
  3. 可选回调filter,用于执行不同的方法运行不同的callback类。
      enhancer.setSuperclass(clazz);
      enhancer.setCallbacks(new Callback[] {new CustomCallback(), new CustomCallback2()});
      enhancer.setCallbackFilter(new CustomCallbackFilter());

代理对象生成分析

  enhancer.create(xxx);
    public Object create() {
        classOnly = false;
        argumentTypes = null;
        return createHelper();
    }

    public Object create(Class[] argumentTypes, Object[] arguments) {
        classOnly = false;
        if (argumentTypes == null || arguments == null || argumentTypes.length != arguments.length) {
            throw new IllegalArgumentException("Arguments must be non-null and of equal length");
        }
        this.argumentTypes = argumentTypes;
        this.arguments = arguments;
        return createHelper();
    }

create 有两个重载的方法,分别用于调用无参的构造方法和有参方法。最后统一调用createHelper();

private Object createHelper() {
        preValidate();
        Object key = KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,
                ReflectUtils.getNames(interfaces),
                filter == ALL_ZERO ? null : new WeakCacheKey(filter),
                callbackTypes,
                useFactory,
                interceptDuringConstruction,
                serialVersionUID);
        this.currentKey = key;
        Object result = super.create(key);
        return result;
    }

    private void preValidate() {
        if (callbackTypes == null) {
            callbackTypes = CallbackInfo.determineTypes(callbacks, false);
            validateCallbackTypes = true;
        }
        if (filter == null) {
            if (callbackTypes.length > 1) {
                throw new IllegalStateException("Multiple callback types possible but no filter specified");
            }
            filter = ALL_ZERO;
        }
    }

首先参数校验,且如果没有设置filter,默认ALL_ZERO。只调用第一个callback回调类。
接着,用上文创建出的代理类 net.sf.cglib.proxy.Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72,调newInstance方法,实例化出一个Enhancer$EnhancerKey的实例。Enhancer$EnhancerKeys实例的属性保存了原始类的信息和设置的各种回调信息。具体参考附录1

有了这些信息,就可以基于此来创建子类实现。此时的this.currentKey=key=EnhancerKey的类对象。

super.create() 又回到AbstractClassGenerator的方法实现:

    protected Object create(Object key) {
        try {
            ClassLoader loader = getClassLoader();
            Map cache = CACHE;
            ClassLoaderData data = cache.get(loader);
            if (data == null) {
                synchronized (AbstractClassGenerator.class) {
                    cache = CACHE;
                    data = cache.get(loader);
                    if (data == null) {
                        Map newCache = new WeakHashMap(cache);
                        data = new ClassLoaderData(loader);
                        newCache.put(loader, data);
                        CACHE = newCache;
                    }
                }
            }
            this.key = key;
            Object obj = data.get(this, getUseCache());
            if (obj instanceof Class) {
                return firstInstance((Class) obj);
            }
            return nextInstance(obj);
        } catch (RuntimeException e) {
            ...
    }

跟之前的区别是CACHE已经初始化过,直接看data.get(this, getUserCache()); 此时的this是Enhancer对象。

    public Object get(AbstractClassGenerator gen, boolean useCache) {
            if (!useCache) {
              return gen.generate(ClassLoaderData.this);
            } else {
              Object cachedValue = generatedClasses.get(gen);
              return gen.unwrapCachedValue(cachedValue);
            }
        }

整个过程跟之前的执行顺序一样,同样直接进入generatedClasses.get(gen);

  public V get(K key) {
        final KK cacheKey = keyMapper.apply(key);
        Object v = map.get(cacheKey);
        if (v != null && !(v instanceof FutureTask)) {
            return (V) v;
        }

        return createEntry(key, cacheKey, v);
    }

    protected V createEntry(final K key, KK cacheKey, Object v) {
        FutureTask task;
        boolean creator = false;
        if (v != null) {
            // Another thread is already loading an instance
            task = (FutureTask) v;
        } else {
            task = new FutureTask(new Callable() {
                public V call() throws Exception {
                    return loader.apply(key);
                }
            });
            Object prevTask = map.putIfAbsent(cacheKey, task);
            if (prevTask == null) {
                // creator does the load
                creator = true;
                task.run();
            } else if (prevTask instanceof FutureTask) {
                task = (FutureTask) prevTask;
            } else {
                return (V) prevTask;
            }
        }

        V result;
        try {
            result = task.get();
        } catch (InterruptedException e) {
            ...
        }
        if (creator) {
            map.put(cacheKey, result);
        }
        return result;
    }

一样进入createEntry,因为此时的loader.apply(key); key是Enhancer对象,因此到此出现子类不同的generate实现。也就是Enhancer的实现。

Enhancer.generate()

protected Class generate(ClassLoaderData data) {
        validate();
        if (superclass != null) {
            setNamePrefix(superclass.getName());
        } else if (interfaces != null) {
            setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName());
        }
        return super.generate(data);
    }

同样先校验回调参数的正确性,在按照统一的命名规则来设置代理类的名称,一般格式为:
SomeClass$$EnhancerByCGLIB$$54d34479
回到父类的generate之后,调用过程同上,最后会继续调用子类(Enhancer)的generateClass(cw);

public void generateClass(ClassVisitor v) throws Exception {
        Class sc = (superclass == null) ? Object.class : superclass;

        if (TypeUtils.isFinal(sc.getModifiers()))
            throw new IllegalArgumentException("Cannot subclass final class " + sc.getName());
        List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors()));
        filterConstructors(sc, constructors);

        // Order is very important: must add superclass, then
        // its superclass chain, then each interface and
        // its superinterfaces.
        List actualMethods = new ArrayList();
        List interfaceMethods = new ArrayList();
        final Set forcePublic = new HashSet();
        getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic);

        List methods = CollectionUtils.transform(actualMethods, new Transformer() {
            public Object transform(Object value) {
                Method method = (Method)value;
                int modifiers = Constants.ACC_FINAL
                    | (method.getModifiers()
                       & ~Constants.ACC_ABSTRACT
                       & ~Constants.ACC_NATIVE
                       & ~Constants.ACC_SYNCHRONIZED);
                if (forcePublic.contains(MethodWrapper.create(method))) {
                    modifiers = (modifiers & ~Constants.ACC_PROTECTED) | Constants.ACC_PUBLIC;
                }
                return ReflectUtils.getMethodInfo(method, modifiers);
            }
        });
        // 后面还有很多生成字节码的代码

这里截取一部分,主要做的事情是将原始类的所有方法封装成MethodWrapper,(除了自定义的方法外,还有toString、equals、hashCode、clone这四个方法)。将这些方法结合ASM来生成代理类的class对象,跟上面过程一样,加载到jvm并缓存,缓存的key就是EnhancerKey里的所有参数,value就是class对象。代理类生成的代码参考附录2。

          Object obj = data.get(this, getUseCache());
            if (obj instanceof Class) {
                return firstInstance((Class) obj);
            }

代理类生成后,回到最上层的create方法,实例化代理对象,返回给业务代码。

MethodWrapper

private static final MethodWrapperKey KEY_FACTORY =
      (MethodWrapperKey)KeyFactory.create(MethodWrapperKey.class);

MethodWrapper 也是cglib中的一个辅助类,内部封装了原始类的所有方法签名信息,同样是为了复用,生成过程也同样是由KeyFactory来创建,执行过程跟EnhancerKey的生成完全一样。生成后的代码参考附录3

        Object o = enhancer.create();

至此,enhancer.create(); 代理类创建完成。到此会生成2个辅助类和1个业务代理类
Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72 辅助类:用于封装代理类的信息
MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7 辅助类:用于封装代理类的所有方法
SomeClass$$EnhancerByCGLIB$$1c48545c 业务类:真正的代理类

业务方法执行

     SomeClass proxy = (SomeClass)new CGLibProxy(SomeClass.class).proxy();
     proxy.doSomething();

既然是代理类,我们就要参考附录2的代理类代码

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

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

在构建这个doSomething的方法时,就已经指定好使用CALLBACK_0,也就是配置的第一个回调类,调用回调类的intercept方法。
intercept方法几个参数分别是代理类实例对象,Method类型的doSomething,doSomething方法参数,MethodProxy的对象。
其中需要着重看下MethodProxy的创建过程。

        Method[] var10000 = ReflectUtils.findMethods(new String[]{"doSomething", "()V", "doOtherthing", "()V"}, (var1 = Class.forName("com.kuaishou.is.proxy.SomeClass")).getDeclaredMethods());
        CGLIB$doSomething$0$Method = var10000[0];
        CGLIB$doSomething$0$Proxy = MethodProxy.create(var1, var0, "()V", "doSomething", "CGLIB$doSomething$0");

MethodProxy.create

      MethodProxy CGLIB$doSomething$0$Proxy = MethodProxy.create(var1, var0, "()V", "doSomething", "CGLIB$doSomething$0");

几个参数分别是代理类的类对象,原始类的类对象,doSomething的返回值类型,原始方法名,代理类生成的方法名。
需要说明的是,从附录2可以看到,代理类已经把原方法doSomething改成了调用intercepter,生成的代理方法调用super.doSomething,就是原方法本身。

public static MethodProxy create(Class c1, Class c2, String desc, String name1, String name2) {
        MethodProxy proxy = new MethodProxy();
        proxy.sig1 = new Signature(name1, desc);
        proxy.sig2 = new Signature(name2, desc);
        proxy.createInfo = new CreateInfo(c1, c2);
        return proxy;
    }

里面其实就是将这几个参数分别构建成几个类,sig1表示原始方法的签名,sig2表示代理类方法的签名,

    private static class CreateInfo {
        Class c1;  //代理类
        Class c2; // 原始类
        NamingPolicy namingPolicy;
        GeneratorStrategy strategy;
        boolean attemptLoad;
        
        public CreateInfo(Class c1, Class c2) {
            this.c1 = c1;
            this.c2 = c2;
            AbstractClassGenerator fromEnhancer = AbstractClassGenerator.getCurrent();
            if (fromEnhancer != null) {
                namingPolicy = fromEnhancer.getNamingPolicy();
                strategy = fromEnhancer.getStrategy();
                attemptLoad = fromEnhancer.getAttemptLoad();
            }
        }
    }

CreateInfo保存了两个类对象和代理类的生成策略。

此时回到自定义的MethodInterceptor实现类,根据调用过程我们知道,代理类最终会将调用引回到intercept方法上,intercept将是我们进行方法扩展的地方,扩展的方式一般是:前置扩展,原方法调用,后置扩展。

现在要说明此时要如何进行原方法的调用?

我们已经代理类的doSomething方法已经被改写,所以不能像jdk那样直接通过method.invoke调用,需要找到原始类的方法实现。
这里我们只能通过methodProxy来调用到原始方法,因为methodProxy已经存储了原始类和代理类,也存储了他们各自的方法。
methodProxy 提供了两个调用方法,invoke用于调用代理类的当前方法,invokeSuper用于调用原始类的当前方法。

public class CustomCallback implements MethodInterceptor {

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

看下invokeSuper的具体实现

MethodProxy.invokeSuper

    private volatile FastClassInfo fastClassInfo;

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

      private void init() {
        /* 
         * Using a volatile invariant allows us to initialize the FastClass and
         * method index pairs atomically.
         * 
         * Double-checked locking is safe with volatile in Java 5.  Before 1.5 this 
         * code could allow fastClassInfo to be instantiated more than once, which
         * appears to be benign.
         */
        if (fastClassInfo == null) {
            synchronized (initLock) {
                if (fastClassInfo == null) {
                    CreateInfo ci = createInfo;

                    FastClassInfo fci = new FastClassInfo();
                    fci.f1 = helper(ci, ci.c1);
                    fci.f2 = helper(ci, ci.c2);
                    fci.i1 = fci.f1.getIndex(sig1);
                    fci.i2 = fci.f2.getIndex(sig2);
                    fastClassInfo = fci;
                    createInfo = null;
                }
            }
        }
    }

   private static FastClass helper(CreateInfo ci, Class type) {
        FastClass.Generator g = new FastClass.Generator();
        g.setType(type);
        g.setClassLoader(ci.c2.getClassLoader());
        g.setNamingPolicy(ci.namingPolicy);
        g.setStrategy(ci.strategy);
        g.setAttemptLoad(ci.attemptLoad);
        return g.create();
    }

invokeSuper 调用分为以下几步:

  1. 通过double check来完成fastClassInfo全局变量的创建
  2. 创建过程中生成FastClass的辅助类
  3. 调用invoke完成原始类方法的调用

在调用helper方法时,会生成FastClass的辅助类,命名为com.kuaishou.is.proxy.SomeClass$$FastClassByCGLIB$$a7b28414, 对应原始类的方法index
SomeClass$$EnhancerByCGLIB$$4ef3bf64$$FastClassByCGLIB$$87e87332.class 对应代理类的方法index
fc1.f1 和 fc1.f2 就是两个辅助类创建的实例对象。

其中FastClass的辅助类的生成还是之前的老套路,会生成一个
具体的实现是在FastClass的内部类Generator的generateClass方法

      public void generateClass(ClassVisitor v) throws Exception {
            new FastClassEmitter(v, getClassName(), type);
        }

这个FastClassEmitter会根据传入的type也就是原始类class,基于此生成一系列方法内部实现,主要使用的方法就是getIndex,即给不同方法定义索引位置。参考附录4和5

后续通过getIndex方法来将i1和i2分别记录原始类和代理类中当前方法的索引值。

初始化完成后会调用invoke方法,

return fci.f2.invoke(fci.i2, obj, args);

f2是代理类对象, i2是代理后的方法索引值,obj是代理类实例对象。
可以知道其实是在调用代理类实例对象的代理方法,本质就是super.原方法。

至此完成原方法的调用。

这样做的目的就是通过给方法签名进行标记索引值,在调用时根据签名来找到方法,触发代理类的方法调用动作,避免出现反射动作。

总结

整体的执行过程分几部:

  1. 在Enhancer对象构建时,通过KeyFactory完成Enhancer$EnhancerKey的构建,Enhancer$EnhancerKey 用于封装原始类的各种信息及回调配置。
  2. enhancer.create(); 主要就是在完成代理类的结构定义
    2.1 通过继承原始类,重写业务方法,改成内部调用回调类的invoke,开放扩展;
    2.2 补充代理方法来完成super.原方法调用,即保留原方法调用;
    2.3 将方法封装成MethodProxy,作为参数传递给invoke,提供外部扩展能力。
  3. invoke内的实现扩展的同时,调用MethodProxy.invokeSuper来调用原方法。
  4. MethodProxy封装了方法的实际调用,在内部定义了一个内部类FastClassInfo实现索引值查找方法,触发调用,避免反射。
  5. FastClass也会给每个原始类生成一个辅助类,记录方法和索引值的映射关系,在第一次调用业务方法时完成生成。

ps:
KeyFactory工厂定义不同的key的生成规则,每种key的职责不同,有不同的参数要求。同一种key通过不同的参数生成具体的代理类class对象,并将key参数和class对象一一对应缓存起来,实现复用的目的。
每种key有自己的generate方法,通过继承AbstractClassGenerator,在KeyFactory创建代理类class对象的过程中,调用自身实现的generate,并结合自身key的参数要求,(包括回调的设置),来基于asm生成代理类的字节码byte[],并封装成WeakReference缓存。

附录

因为的代码块不能折叠,所有代理类的代码都移到另一篇文章方便查看。动态代理实现源码剖析 —— 附录: cglib生成代理类

你可能感兴趣的:(动态代理实现源码剖析 —— 深入分析cglib动态代理)