CGlib动态代理中Enhancer.create()函数的逻辑
来源:互联网 发布:软件平台架构 编辑:程序博客网 时间:2024/06/05 07:11
整个过程如下:
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; }
阅读全文
0 0
- CGlib动态代理中Enhancer.create()函数的逻辑
- cglib中Enhancer的简单使用
- cglib中Enhancer的简单使用
- cglib中Enhancer的简单使用
- cglib中Enhancer的简单使用
- cglib jar包中Enhancer的简单使用
- cglib的动态代理
- Cglib的动态代理
- Java的CGLib动态代理
- CGLIB 动态代理的实现
- 基于cglib的动态代理
- 代理实现机制,Java中动态代理和cglib动态代理的实现机制
- java 代理模式 CGLIB的动态代理
- Spring中AOP的两种代理方式(Java动态代理和CGLIB代理)
- Spring中AOP的两种代理方式(Java动态代理和CGLIB代理)
- Spring中AOP的两种代理方式(Java动态代理和CGLIB代理)
- Spring中AOP的两种代理方式(Java动态代理和CGLIB代理)
- Spring中AOP的两种代理方式(Java动态代理和CGLIB代理)
- Codeforces 854 A Fraction
- 【知了堂学习笔记】JfreeChart制作一些简单的报表
- Whitelabel Error Page(2)之Internal Server Error
- struts2中 ServletActionContext与ActionContext区别
- Swift中懒加载
- CGlib动态代理中Enhancer.create()函数的逻辑
- 线性时间排序
- 虚拟机中linux系统启动的tomcat无法在本机访问的问题
- 缓存穿透与缓存雪崩
- 软件测试知识点
- 直方图均衡化
- Python——安装Scrapy时出现各种错误
- hdu2825-(AC自动机+状压DP)
- Java开发牛人十大必备网站