cglib底层源码分析

  • Post author:
  • Post category:其他





cglib如何代理增强

cglib是⼀种动态代理技术,可以针对类来⽣成⼀个代理对象。

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

现在利⽤cglib对UserService类中的test()⽅法进⾏增强:

public class Main {
    public static void main(String[] args) {
        final UserService target = new UserService();
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(UserService.class);
        enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[]
            objects, MethodProxy methodProxy) throws Throwable {
                 // test⽅法增加了其他逻辑
                if (method.getName().equals("test")) {
                    System.out.println("before...");
                    Object result = method.invoke(target, objects);
                    System.out.println("after...");
                    return result;
                }
                // 其他⽅法正常执⾏
                return method.invoke(target, objects);
                }
            }});
        UserService userService = (UserService) enhancer.create();
        userService.test();
    }
}



cglib能否代理接⼝

定义⼀个UserInterface接⼝:

public interface UserInterface {
    public void test();
}

接下来利⽤cglib来代理⼀个接⼝

public class Main {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(UserInterface.class);
        enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[]
                objects, MethodProxy methodProxy) throws Throwable {
                if (method.getName().equals("test")) {
                    System.out.println("切⾯逻辑...");
                }
            return null;
            }
        }});
        UserInterface userInterface = (UserInterface) enhancer.create();
        userInterface.test();
    }
}

可以正常运⾏的



cglib代理⼀个类和代理⼀个接⼝的底层有什么区别呢

我们可以通过设置

-Dcglib.debugLocation=D:\personal\base\cglib\cglib\target\classes

在这里插入图片描述

cglib就会将⽣成的代理类放到上⾯所指定的路径上。那么我们分别来看看cglib代理类和接⼝时所产⽣的代理类。

UserService的代理类

public class UserService$$EnhancerByCGLIB$$4d890297 extends UserService implements Factory {
    final void CGLIB$test$0() {
        super.test();
    }

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

UserInterface的代理类

public class UserInterface$$EnhancerByCGLIB$$20ecfdd extends UserService implements Factory {
    final void CGLIB$test$2() {
        super.test();
    }

    public final void test() {
        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$test$2$Method, CGLIB$emptyArgs, CGLIB$test$2$Proxy);
        } else {
            super.test();
        }
    }
}

可以发现类区别不⼤UserService代理类是UserService的⼦类,UserInterface代理类实现了UserInterface。

以UserService代理类举例

test()⽅法内会去调⽤所设置的Callbacks中的intercept(),相当于执⾏增强逻辑,如果没有Callbacks,则会执⾏super.test(),那么我们⾃然能想到,如果不设置Callbacks,那是不是就能正常执⾏?

Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
UserService userService = (UserService) enhancer.create();
userService.test();

运⾏这上述段代码时,cglib在构造代理对象时就会报⼀个没有Callbacks的空指针异常

查看代理类中的

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

这个⽅法我们并不能直接调⽤,要通过所设置的Callback,也就是MethodInterceptor中的MethodProxy对象来调⽤,MethodProxy对象表示⽅法代理,举例,假如UserService代理对象在执⾏test()⽅法,那么当执⾏流程进⼊到intercept()⽅法时,MethodProxy对象表示的就是test()⽅法,但是我们现在知道了在UserService类和UserService代理类中都有test()⽅法,所以MethodProxy对象代理的就是这两个test()

// o表示当前代理对象,target表示被代理对象
// 执⾏UserService代理对象的CGLIB$test$0()⽅法,也就是执⾏UserService代理对象的⽗类的test()
Object result = methodProxy.invokeSuper(o, objects);
// 执⾏UserService对象的CGLIB$test$0()⽅法,会报错,调⽤invokerSuper只能传⼊代理对象
Object result = methodProxy.invokeSuper(target, objects);
// 执⾏UserService对象的test()
Object result = methodProxy.invoke(target, objects);
// 执⾏UserService代理对象的test(); ⼜会进到拦截器,栈溢出
Object result = methodProxy.invoke(o, objects);

执⾏methodProxy.invokeSuper()⽅法时,就会去执⾏CGLIB$test



0

(

)

⽅法。因此

c

g

l

i

b

的⼤概⼯作原理是:

c

g

l

i

b

会根据所设置的

S

u

p

e

r

c

l

a

s

s

,⽣成代理类作为其⼦类,并且会重写

S

u

p

e

r

c

l

a

s

s

中的⽅法,

S

u

p

e

r

c

l

a

s

s

中的某⼀个⽅法,⽐如

t

e

s

t

(

)

,相应的在代理类中会对应两个⽅法,⼀个是重写的

t

e

s

t

(

)

,⽤来执⾏增强逻辑,⼀个是

C

G

L

I

B

0()⽅法。 因此cglib的⼤概⼯作原理是: cglib会根据所设置的Superclass,⽣成代理类作为其⼦类,并且会重写Superclass中的⽅法,Superclass中的某⼀个⽅法,⽐如test(),相应的在代理类中会对应两个⽅法,⼀个是重写的test(),⽤来执⾏增强逻辑,⼀个是CGLIB






0


(


)





法。因此


c


g


l


ib














作原理是:


c


g


l


ib


会根据所设置的


S


u


p


erc


l


a


ss








成代理类作为其





类,并且会重写


S


u


p


erc


l


a


ss


中的





法,


S


u


p


erc


l


a


ss


中的某











法,








t


es


t


(


)


,相应的在代理类中会对应两个





法,





个是重写的


t


es


t


(


)








来执





增强逻辑,





个是


CG


L


I


B





test$0(),会直接调⽤super.test(),是让MethodProxy对象来⽤的。



cglib代理类是怎么⽣成的

查看完整代码:

public class UserService$$EnhancerByCGLIB$$4d890297 extends UserService implements Factory {
    private boolean CGLIB$BOUND;
    public static Object CGLIB$FACTORY_DATA;
    private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
    private static final Callback[] CGLIB$STATIC_CALLBACKS;
    private MethodInterceptor CGLIB$CALLBACK_0;
    private static Object CGLIB$CALLBACK_FILTER;
    private static final Method CGLIB$test$0$Method;
    private static final MethodProxy CGLIB$test$0$Proxy;
    private static final Object[] CGLIB$emptyArgs;
    private static final Method CGLIB$equals$1$Method;
    private static final MethodProxy CGLIB$equals$1$Proxy;
    private static final Method CGLIB$toString$2$Method;
    private static final MethodProxy CGLIB$toString$2$Proxy;
    private static final Method CGLIB$hashCode$3$Method;
    private static final MethodProxy CGLIB$hashCode$3$Proxy;
    private static final Method CGLIB$clone$4$Method;
    private static final MethodProxy CGLIB$clone$4$Proxy;

    static void CGLIB$STATICHOOK1() {
        CGLIB$THREAD_CALLBACKS = new ThreadLocal();
        CGLIB$emptyArgs = new Object[0];
        Class var0 = Class.forName("com.zhouyu.UserService$$EnhancerByCGLIB$$4d890297");
        Class var1;
        Method[] var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
        CGLIB$equals$1$Method = var10000[0];
        CGLIB$equals$1$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$1");
        CGLIB$toString$2$Method = var10000[1];
        CGLIB$toString$2$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$2");
        CGLIB$hashCode$3$Method = var10000[2];
        CGLIB$hashCode$3$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$3");
        CGLIB$clone$4$Method = var10000[3];
        CGLIB$clone$4$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$4");
        CGLIB$test$0$Method = ReflectUtils.findMethods(new String[]{"test", "()V"}, (var1 = Class.forName("com.zhouyu.UserService")).getDeclaredMethods())[0];
        CGLIB$test$0$Proxy = MethodProxy.create(var1, var0, "()V", "test", "CGLIB$test$0");
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        return null;
    }

    public UserService$$EnhancerByCGLIB$$4d890297() {
        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) {
        UserService$$EnhancerByCGLIB$$4d890297 var1 = (UserService$$EnhancerByCGLIB$$4d890297)var0;
        if (!var1.CGLIB$BOUND) {
            var1.CGLIB$BOUND = true;
            Object var10000 = CGLIB$THREAD_CALLBACKS.get();
            if (var10000 == null) {
                var10000 = CGLIB$STATIC_CALLBACKS;
                if (var10000 == null) {
                    return;
                }
            }

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

    }

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

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

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

发现newInstance()⽅法会重新⽣成⼀个代理对象,setCallbacks()和getCallbacks()可以⽤来设置或获取增强逻辑。

不仅只有test()⽅法会⽣成对应的两个⽅法,其他⽅法也会⽣成,⽐如:equals() toString()hashCode() clone()

代理类中有⼀个代理块,会调⽤CGLIB



S

T

A

T

I

C

H

O

O

K

1

(

)

,这个⽅法主要就是给属性赋值,构造⼀个

T

h

r

e

a

d

L

o

c

a

l

对象给

C

G

L

I

B

STATICHOOK1(),这个⽅法主要就是给属性赋值, 构造⼀个ThreadLocal对象给CGLIB






ST


A


T


I


C


H


OO


K


1


(


)


,这个





法主要就是给属性赋值,构造








T


h


re


a


d


L


oc


a


l


对象给


CG


L


I


B





THREAD_CALLBACKS属性

获取UserService类中的test⽅法的Method对象给CGLIB$test



0

0






0





Method属性

构造test()⽅法所对应的MethodProxy对象给CGLIB$test



0

0






0





Proxy属性 等

有⼀个⽅法是cglib在⽣成代理对象后,会主动调⽤的⼀个⽅法,这个⽅法是CGLIB$SET_THREAD_CALLBACKS

在这里插入图片描述

  1. cglib⽣成代理类
  2. 然后调⽤构造⽅法得到代理对象
  3. 然后cglib调⽤代理对象的CGLIB



    S

    E

    T

    T

    H

    R

    E

    A

    D

    C

    A

    L

    L

    B

    A

    C

    K

    S

    (

    )

    ⽅法,所设置的

    C

    a

    l

    l

    b

    a

    c

    k

    s

    设置到

    C

    G

    L

    I

    B

    SET_THREAD_CALLBACKS()⽅法,所设置的Callbacks设置到CGLIB






    SE



    T










    T


















    H


    RE


    A



    D










    C


















    A


    LL


    B


    A


    C


    K


    S


    (


    )





    法,所设置的


    C


    a


    ll


    ba


    c


    k


    s


    设置到


    CG


    L


    I


    B





    THREAD_CALLBACKS这个ThreadLocal中

  4. 后续代理对象在执⾏test()⽅法时,就会从CGLIB$THREAD_CALLBACKS拿到所设置的Callbacks,调⽤其intercept()⽅法

    代理类的⽣成逻辑就是:
  5. ⽣成类的定义,实现UserService和Factory接⼝
  6. 根据UserService类中的⽅法⽣成代理类中对应的⽅法和属性
  7. ⽣成⼀些辅助的属性和⽅法



MethodProxy是怎么实现的


MethodProxy对象,表示⼀个⽅法的代理,⽐如UserSerivce中的test()⽅法,在对应的代理类中会有对应的两个⽅法:

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

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

MethodProxy对象代理就是这两个⽅法

// 表示执⾏某个对象的CGLIB$test$0()⽅法,如果o中没有CGLIB$test$0()⽅法则会报错
methodProxy.invokeSuper(o, args)
// 表示执⾏某个对象的test⽅法
methodProxy.invoke(o, args)

MethodProxy对象的创建,创建的⼊⼝在代理类中:

CGLIB$test$0$Proxy = MethodProxy.create(var1, var0, "()V", "test","CGLIB$test$0");
public static MethodProxy create(Class c1, Class c2, String desc, String name1, String name2) {
    // c1是UserService
    // c2是UserService代理类
    // desc被代理方法的返回值类型
    // name1是被代理方法名比如test
    // name2是代理类中的CGLIB$test$0方法,会调用super.test()

    MethodProxy proxy = new MethodProxy();
    proxy.sig1 = new Signature(name1, desc);  // 被代理方法签名,也就是代表void test()
    proxy.sig2 = new Signature(name2, desc);  // 代理方法签名,也就是void CGLIB$test$0()
    proxy.createInfo = new CreateInfo(c1, c2); // CreateInfo中表示的就是被代理类和代理类的信息
    return proxy;
}

MethodProxy对象中主要有三个属性:

  1. sig1,表示test⽅法
  2. sig2,表示CGLIB$test$0⽅法
  3. createInfo,表示UserService类和UserService代理类

MethodProxy的invoke()和invokeSuper()⽅法:

public Object invoke(Object obj, Object[] args) throws Throwable {
    try {
        init();
        FastClassInfo fci = fastClassInfo;

        // f1表示被代理类的FastClass代理类,i1表示被代理方法的下标,这里就是去执行test()方法,具体执行的是哪个对象就看obj
        return fci.f1.invoke(fci.i1, obj, args);
    } catch (InvocationTargetException e) {
        throw e.getTargetException();
    } catch (IllegalArgumentException e) {
        if (fastClassInfo.i1 < 0)
            throw new IllegalArgumentException("Protected method: " + sig1);
        throw e;
    }
}
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
    try {
        init();
        FastClassInfo fci = fastClassInfo;

        // f2表示UserService代理类的FastClass代理类,i2表示代理方法的下标,这里就是去执行CGLIB$test$0方法,具体执行的是哪个对象就看obj
        return fci.f2.invoke(fci.i2, obj, args);
    } catch (InvocationTargetException e) {
        throw e.getTargetException();
    }
}

⾸先都需要⽤到⼀个FastClassInfo对象,这个对象是在init()⽅法构造的。

private void init()
    {
        if (fastClassInfo == null)
        {
            synchronized (initLock)
            {
                if (fastClassInfo == null)
                {
                    // CreateInfo中存储了代理类和被代理类
                    CreateInfo ci = createInfo;

                    FastClassInfo fci = new FastClassInfo();
                    fci.f1 = helper(ci, ci.c1); // 被代理类的FastClass代理类,也就是UserService$$FastClass...
                    fci.f2 = helper(ci, ci.c2); // 代理类的FastClass代理类,也就是UserService$$EnhancerBy...$$FastClasss...


//                     被代理方法签名,也就是代表void test()
//                     代理方法签名,也就是void CGLIB$test$0()

                    // 预先生成每个方法所对应的下标,调用时就可以直接利用下标找到方法了,性能高
                    fci.i1 = fci.f1.getIndex(sig1); // 获取方法签名sig1在被代理类的FastClass代理类中的下标,后续根据下标找到对应的方法,sig1表示被代理方法test()
                    fci.i2 = fci.f2.getIndex(sig2); // 获取方法签名sigsig2在代理类的FastClass代理类中的下标,后续根据下标找到对应的方法,sig2表示代理方法CGLIB$test$0()
                    fastClassInfo = fci;
                    createInfo = null;
                }
            }
        }
    }

FastClassInfo对象中主要有四个属性:

  1. f1,UserService类对应的⼀个FastClass代理对象
  2. f2,UserService代理类对应的⼀个FastClass代理对象
  3. i1,test⽅法在UserService类对应的⼀个FastClass代理对象中的下标
  4. i2,CGLIB$test$0⽅法在UserService代理对对应的⼀个FastClass代理对象

两个类类似,都是针对某⼀个类的FastClass代理类,所以我们好好看⼀下UserService所对应的FastClass,该类主要有:

  1. ⼀个构造⽅法
  2. public int getIndex(Signature var1)
  3. public int getIndex(String var1, Class[] var2)
  4. public int getIndex(Class[] var1)
  5. public Object invoke(int var1, Object var2, Object[] var3)
  6. public Object newInstance(int var1, Object[] var2)7. public int getMaxIndex()

    FastClass的作⽤是提⾼⽅法的执⾏速度,按照正常的实现,当我们调⽤MethodProxy对象的invoke()或invokeSuper()⽅法时,⾸先应该要做到的就是找到对应的Method对象,⽐如:1. 执⾏invoke(),要找到test⽅法对应的Method对象2. 执⾏invokeSuper(),要找到CGLIB$test$0()⽅法对应的Method对象然后利⽤反射来执⾏Method。

    然而FastClass的机制就是预先把UserService类或UserService代理类中的所有⽅法做⼀个索引
public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
    UserService var10000 = (UserService)var2;
    int var10001 = var1;

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

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

调了这个⽅法,就会得到当前要执⾏的⽅法所对应的index

init方法 两个helper()⽅法就是分别去⽣成UserService类和UserService代理类所对应的FastClass代理类。接下来的两个getIndex(),就是分别去:

  1. 去UserService类对应的FastClass代理类中找到test()⽅法的下标i1
  2. 去UserService代理类对应的FastClass代理类中找到CGLIB$test$0()⽅法的下标i2然后把两个下标都记录在fastClassInfo中。
  3. invoke:fci.f1.invoke(fci.i1, obj, args),执⾏UserService类对应的FastClass代理类的invoke⽅法
  4. invokeSuper:fci.f2.invoke(fci.i2, obj, args),执⾏UserService代理类对应的FastClass代理类的invoke⽅如

    ⽐如下标为0,就会执⾏var10000.test();⽽var10000,是所传⼊对象强制转化为4d890297类的对象,4d890297其实就是UserService的代理类。所以我们可以发现,当执⾏invokeSuper()这个⽅法时,不能传⼊UserService对象,只能传⼊UserService的代理对象,不然就不能转换成为UserService代理类类型。

    因此FastClass,快的地⽅就是预先把⽅法信息都⽣成好了,在真正调⽤的时候,不⽤再去找Method对象,⽽是直接就执⾏⽅法了



版权声明:本文为qq_35583881原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。