Cglib FastClass例子

image.png

DemoService 原始类
DemoService$$FastClassByCGLIB$$3215ecb4 原始类的FastClass

DemoService$$EnhancerByCGLIB$$c23dc77c DemoService的代理类
DemoService$$EnhancerByCGLIB$$c23dc77c$$FastClassByCGLIB$$396d31d2 代理类的FastClass

   static void CGLIB$STATICHOOK1() {
        CGLIB$THREAD_CALLBACKS = new ThreadLocal();
        CGLIB$emptyArgs = new Object[0];

        // 生成的代理类
        Class class_ = Class.forName("com.zhiyin.cglib.cando.DemoService$$EnhancerByCGLIB$$c23dc77c");
        Class class_2 = Class.forName("java.lang.Object");
        Method[] arrmethod = ReflectUtils.findMethods((String[])new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (Method[])class_2.getDeclaredMethods());
        CGLIB$equals$1$Method = arrmethod[0];
        CGLIB$equals$1$Proxy = MethodProxy.create(class_2, class_, (String)"(Ljava/lang/Object;)Z", (String)"equals", (String)"CGLIB$equals$1");
        CGLIB$toString$2$Method = arrmethod[1];
        CGLIB$toString$2$Proxy = MethodProxy.create(class_2, class_, (String)"()Ljava/lang/String;", (String)"toString", (String)"CGLIB$toString$2");
        CGLIB$hashCode$3$Method = arrmethod[2];
        CGLIB$hashCode$3$Proxy = MethodProxy.create(class_2, class_, (String)"()I", (String)"hashCode", (String)"CGLIB$hashCode$3");
        CGLIB$clone$4$Method = arrmethod[3];
        CGLIB$clone$4$Proxy = MethodProxy.create(class_2, class_, (String)"()Ljava/lang/Object;", (String)"clone", (String)"CGLIB$clone$4");

        // 原始类
        class_2 = Class.forName("com.zhiyin.cglib.cando.DemoService");

        
        CGLIB$hello$0$Method = ReflectUtils.findMethods((String[])new String[]{"hello", "(Ljava/lang/String;)Ljava/lang/String;"}, (Method[])class_2.getDeclaredMethods())[0];
        // hello方法代理 参数分别为 原始类 代理类 参数与返回值描述 方法名 代理方法名
        CGLIB$hello$0$Proxy = MethodProxy.create(class_2, class_, (String)"(Ljava/lang/String;)Ljava/lang/String;", (String)"hello", (String)"CGLIB$hello$0");
    }

// 真正的服务方法
    final String CGLIB$hello$0(String string) {
        return super.hello(string);
    }

// 代理方法
    public final String hello(String string) {
        MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
        if (methodInterceptor == null) {
            DemoService$$EnhancerByCGLIB$$c23dc77c.CGLIB$BIND_CALLBACKS((Object)this);
            methodInterceptor = this.CGLIB$CALLBACK_0;
        }
        if (methodInterceptor != null) {
            return (String)methodInterceptor.intercept((Object)this, CGLIB$hello$0$Method, new Object[]{string}, CGLIB$hello$0$Proxy);
        }
        return super.hello(string);
    }

参数见上面说明

  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;
    }
    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();
                    // ci.c1是原始类DemoService
                    fci.f1 = helper(ci, ci.c1);
                    // ci.c2是代理类
                    fci.f2 = helper(ci, ci.c2);
                    // hello
                    fci.i1 = fci.f1.getIndex(sig1);
                    // CGLIB$hello$0
                    fci.i2 = fci.f2.getIndex(sig2);
                    fastClassInfo = fci;
                    createInfo = null;
                }
            }
        }
    }

调用这里调用的是 代理类的代理方法

  public Object invokeSuper(Object obj, Object[] args) throws Throwable {
        try {
            // 初始化fastClassInfo
            init();
            FastClassInfo fci = fastClassInfo;
            // 调用代理类的CGLIB$hello$0方法
            return fci.f2.invoke(fci.i2, obj, args);
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,314评论 19 139
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 5,806评论 0 9
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,898评论 18 399
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,046评论 25 709
  • 一 最近在看一些有关影视编剧的教材,有一句希区柯克的名言印象深刻——“电影就是将平淡无奇的片段切去去以后的人生”。...
    逐日free阅读 2,790评论 0 0