CGlib动态代理中Enhancer.create()函数的逻辑

整个过程如下:

Cglib根据父类,Callback, Filter 及一些相关信息生成key.
然后根据key 生成对应的子类的二进制表现形式
使用ClassLoader装载对应的二进制,生成Class对象,并缓存
最后实例化Class对象,并缓存

下面是相对应的关键代码.

1)Cglib如何生成的Class的二进制文件
针对不同场景, CGlib准备了不同的Class生成方法, 他们都实现了接口: ClassGenerator. 下面我们只针对默认的Enhancer来分析.

Java代码
//此函数会被AbstractClassGenerator.create间接调用,并会在create函数中将结果缓存.

Enhancer.generateClass(ClassVisitor v)   

//AbstractClassGenerator.create(Object key)  
protected Object create(Object key) {  
    try {  
        Class gen = null;  

        synchronized (source) {  
            ClassLoader loader = getClassLoader();  
            Map cache2 = null;  
            cache2 = (Map)source.cache.get(loader);  
            if (cache2 == null) {  
                cache2 = new HashMap();  
                cache2.put(NAME_KEY, new HashSet());  
                source.cache.put(loader, cache2);  
            } else if (useCache) {  
                Reference ref = (Reference)cache2.get(key);  
                gen = (Class) (( ref == null ) ? null : ref.get());   
            }  
            if (gen == null) {  
                Object save = CURRENT.get();  
                CURRENT.set(this);  
                try {  
                    this.key = key;  

                    if (attemptLoad) {  
                        try {  
                            gen = loader.loadClass(getClassName());  
                        } catch (ClassNotFoundException e) {  
                            // ignore  
                        }  
                    }  
                    if (gen == null) {  
                        //生成的Class的二进制存储  
                        byte[] b = strategy.generate(this);  
                        String className = ClassNameReader.getClassName(new ClassReader(b));  
                        //将类名放入Cache中,Cache实际上是一个Hashset的实例  
                        getClassNameCache(loader).add(className);  
                        //将生成的类装载路JVM  
                        gen = ReflectUtils.defineClass(className, b, loader);  
                    }  

                    if (useCache) {  
                        //将装载的类放入cache  
                        cache2.put(key, new WeakReference(gen));  
                    }  
                    return firstInstance(gen);  
                } finally {  
                    CURRENT.set(save);  
                }  
            }  
        }  
        return firstInstance(gen);  
    } catch (RuntimeException e) {  
        throw e;  
    } catch (Error e) {  
        throw e;  
    } catch (Exception e) {  
        throw new CodeGenerationException(e);  
    }  
}  




2)Cglib生成的Class二进制(byte[])放哪
放在byte数组中,下面这行代码就截取于方法AbstractClassGenerator.create(Object key)
byte[] b = strategy.generate(this);

然后通过 ReflectUtils.defineClass(className, b, loader) 生成对应的Class实例,并缓存入cache2

3)Cglib如何把二进制Load生成的Class

Java代码

//ReflectUtils.defineClass(className, b, loader)  
public static Class defineClass(String className, byte[] b, ClassLoader loader) throws Exception {  
    Object[] args = new Object[]{className, b, new Integer(0), new Integer(b.length), PROTECTION_DOMAIN };  
    //DEFINE_CLASS 是通过静态块来实例化的一个java.lang.ClassLoader.defineClass的方法对象  
    Class c = (Class)DEFINE_CLASS.invoke(loader, args);  
    // Force static initializers to run.  
    Class.forName(className, true, loader);  
    return c;  
}     
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值