Cglib生成的动态代理类源码分析

代码准备

被代理类Teacher

public class Teacher  {
    
    public void say() {
        System.out.println(String.join(",","I'm a teacher"));
    }
}
自定义的MethodInterceptor

CglibProxy和DefaultProxy

//拦截非Object方法
public class CglibProxy implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy proxy) throws Throwable {
        Object result=null;
        before();
        result= proxy.invokeSuper(o,objects);
        after();
        return result;
    }
    public Object before(){
        System.out.println("before invoke ");
        return null;
    }
    public Object after(){
        System.out.println("after invoke");
        return null;
    }
}
//拦截Object方法
public class DefaultProxy implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        if(method.getDeclaringClass()==Object.class){
            return methodProxy.invokeSuper(o,objects);
        }
        return null;
    }
}
 

cglib动态代理使用样列

public class CglibMain {
    public static void main(String[] args) throws IOException {
        Enhancer enhancer=new Enhancer();
        enhancer.setSuperclass(Teacher.class);
        enhancer.setCallbacks(new Callback[]{new DefaultProxy(),new CglibProxy()});
        enhancer.setCallbackFilter(new MethodFilter());
        Teacher proxy= (Teacher) enhancer.create();
        proxy.say();
    }
}
上面是cglib动态代理类的使用步骤,具体的运行是什么,我们需要得到enhancer.create()生成的代理类源码,我们可以通过java的HSDB来查看(https://blog.csdn.net/qq_27378875/article/details/81407989)

---------------------------------分割线--------------------------------------------

cglib动态类源码分析


1、主要生成了下面两个类:
cglib动态生成的Teacher的代理类,可以看出extends了Teacher ,所以我们可以用利用多态强转为Teacher

public class Teacher$$EnhancerByCGLIB$$f312f930 extends Teacher implements Factory 

cglib动态生成的FastClass,这个会在第7步骤讲解

public class Teacher$$EnhancerByCGLIB$$f312f930$$FastClassByCGLIB$$41d4d523 extends FastClass 
2、

Teacher$$EnhancerByCGLIB$$f312f930的主要参数和方法说明

两个MethodInterceptor是我们自己定义的代理处理类,    

private MethodInterceptor CGLIB$CALLBACK_0; //
private MethodInterceptor CGLIB$CALLBACK_1;//我们自己定义的代理处理类,
//这两个属性通过setCallbacks()来赋值
 public void setCallbacks(Callback[] var1) {
        this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0];
        this.CGLIB$CALLBACK_1 = (MethodInterceptor)var1[1];
 }
我们在main方法里调用了 enhancer.setCallbacks(new Callback[]{new DefaultProxy(),new CglibProxy()});

因此

CGLIB$CALLBACK_0=new DefaultProxy();

CGLIB$CALLBACK_1=new CglibProxy()


 Method和MethodProxy(我们现在只分析say()方法,只显示say相关的代码)

private static final Method CGLIB$say$2$Method;//被代理实体类的方法反射类
private static final MethodProxy CGLIB$say$2$Proxy;//cglib的方法代理类,负责的选择调度,每个方法对应一个MethodProxy,后面详细说明
  


 MethodProxy的初始化,很重要

 static void CGLIB$STATICHOOK1() {
        CGLIB$THREAD_CALLBACKS = new ThreadLocal();
        CGLIB$emptyArgs = new Object[0];
        //cglib代理类
        Class var0 = Class.forName("com.speedyao.proxy.Teacher$$EnhancerByCGLIB$$f312f930");
        //在下一行代码可以看出是Object
        Class var1;
        Method[] var10000 = ReflectUtils.findMethods(new String[]{"finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
        CGLIB$finalize$3$Method = var10000[0];
        CGLIB$finalize$3$Proxy = MethodProxy.create(var1, var0, "()V", "finalize", "CGLIB$finalize$3");
     
        var10000 = ReflectUtils.findMethods(new String[]{"getName", "()Ljava/lang/String;", "setName", "(Ljava/lang/String;)V", "say", "()V"}, (var1 = 
        CGLIB$say$2$Method = var10000[2];//
        //这个在下面会用到
        CGLIB$say$2$Proxy = MethodProxy.create(var1, var0, "()V", "say", "CGLIB$say$2");
    }

   MethodProxy.create(var1, var0, "()V", "say", "CGLIB$say$2")的方法代码

  public static MethodProxy create(Class c1, Class c2, String desc, String name1, String name2) {
        MethodProxy proxy = new MethodProxy();
        proxy.sig1 = new Signature(name1, desc);//say()方法
        proxy.sig2 = new Signature(name2, desc);//CGLIB$say$2()方法
        proxy.createInfo = new CreateInfo(c1, c2);
         return proxy;
   }

       
 代理类生成的被代理类相关的方法
     say():代理类重写的say方法,当我们用动态代理类执行say()时,执行的就是这段代码

 public final void say() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_1;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_1;
        }
 
        if (var10000 != null) {
            var10000.intercept(this, CGLIB$say$2$Method, CGLIB$emptyArgs, CGLIB$say$2$Proxy);
        } else {
            super.say();
        }
    }

    CGLIB$say$2()方法,父类是Teacher,所以此方法实际执行的是Teacher.say()

   final void CGLIB$say$2() {
        super.say();
    }
 3、上面主要参数和方法都罗列完了,接下来开始说明调用细节
 Teacher proxy= (Teacher) enhancer.create();
 proxy.say();
通过上面的say()代码快,我们知道最终执行的是
 

var10000.intercept(this, CGLIB$say$2$Method, CGLIB$emptyArgs, CGLIB$say$2$Proxy);

 由上面的参数分析我们得知var1000=new CglibProxy(),所以这一步就是执行我们自定义的intercept方法

o:是this,也就是动态代理对象
method:CGLIB$say$2$Method ,也就是Teacher.say()的反射Method类
objects: CGLIB$emptyArgs,空参数
proxy:CGLIB$say$2$Proxy,方法代理类
 
 public Object intercept(Object o, Method method, Object[] objects, MethodProxy proxy) throws Throwable {
        Object result=null;
        
        //执行前处理
        before();
        //执行被代理类的真实方法
        result= proxy.invokeSuper(o,objects);
        //执行后的处理
        after();
        return result;
    }
 7、分析proxy.invokeSuper(o,objects)如何触发Teacher.say()

看看proxy.invokeSuper(o,objects)代码
 

  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();
        }
    }

通过代码可以看出最终执行代码是
fci.f2.invoke(fci.i2, obj, args);
这行代码关键的两个对象是fci.f2和fci.i2
查看init()方法

 private void init()
    {
 
        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;
                }
            }
        }
    }

通过init()方法,我们得知
fci.f2=helper(ci, ci.c2);
fci.i2 = fci.f2.getIndex(sig2);

fci.f2实际上根据com.speedyao.proxy.Teacher$$EnhancerByCGLIB$$f312f930动态生成的FastClass

fci.f2是CGLIB$say$2方法的索引位
通过下面代码可知上面的结论

static void CGLIB$STATICHOOK1() {    
        Class var0 = Class.forName("com.speedyao.proxy.Teacher$$EnhancerByCGLIB$$f312f930");
         CGLIB$say$2$Proxy = MethodProxy.create(var1, var0, "()V", "say", "CGLIB$say$2");
 }
   public static MethodProxy create(Class c1, Class c2, String desc, String name1, String name2) {
        MethodProxy proxy = new MethodProxy();
        proxy.sig1 = new Signature(name1, desc);//say()方法
        proxy.sig2 = new Signature(name2, desc);//CGLIB$say$2()方法
        proxy.createInfo = new CreateInfo(c1, c2);
         return proxy;
   }
 
  
 

 public class Signature {
    private String name;
    private String desc;
 
    public Signature(String name, String desc) {
        // TODO: better error checking
        if (name.indexOf('(') >= 0) {
            throw new IllegalArgumentException("Name '" + name + "' is invalid");
        }
        this.name = name;
        this.desc = desc;
    }
   }
 

//**
接下来我们就需要fci.f2.invoke(fci.i2, obj, args)做了什么,fci.f2类型是FastClass的子类,就是我们上面提到的动态生成的Class
Teacher$$EnhancerByCGLIB$$f312f930$$FastClassByCGLIB$$41d4d523
反编译的源码如下,只列了关键代码
*/
 
public class Teacher$$EnhancerByCGLIB$$f312f930$$FastClassByCGLIB$$41d4d523 extends FastClass {
    public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
        f312f930 var10000 = (f312f930)var2;
        int var10001 = var1;
 
        try {
            switch(var10001) {
            case 0:
                return new Boolean(var10000.equals(var3[0]));     
            case 13:
                var10000.CGLIB$say$2();
                return null;
            case 19:
                var10000.say();
                return null;
   
            }
        } catch (Throwable var4) {
            throw new InvocationTargetException(var4);
        }
 
        throw new IllegalArgumentException("Cannot find matching method/constructor");
    }
}

通过上面的分析我们得知 var1是CGLIB$say$2的index也就是13,var2是Teacher的代理类对象,
所以实际上执行的代码就是
var10000.CGLIB$say$2();
也就是代理类的CGLIB$say$2方法,如下
 final void CGLIB$say$2() {
        super.say();
  }
  因为代理类extends Teacher,所以实际上执行的代码就是Teacher.say()

8、接下来总结下调用步骤

动态代理类
Teacher$$EnhancerByCGLIB$$f312f930.say()->
自定义的方法拦截器
CglibProxy.intercept(this, CGLIB$say$2$Method, CGLIB$emptyArgs, CGLIB$say$2$Proxy)->
方法代理
MethodProxy.invokeSuper(o,objects)->
动态生成的FastClass子类
Teacher$$EnhancerByCGLIB$$f312f930$$FastClassByCGLIB$$41d4d523.invoke(fci.i2, obj, args)->
动态代理类
Teacher$$EnhancerByCGLIB$$f312f930.CGLIB$say$2()->
被代理对象也就是Teacher
super.say();

以上便是cglib动态代理类的执行步骤,有什么疑问留言答复,反编译源码需要的话可以留言
————————————————
版权声明:本文为CSDN博主「speedyao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010430495/article/details/98756930

猜你喜欢

转载自blog.csdn.net/zzy7075/article/details/107230307