`
flyfoxs
  • 浏览: 297788 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
社区版块
存档分类
最新评论

CGLIB学习札记---Enhancer如何生成子类并装载

 
阅读更多

上一篇博文: CGLIB学习札记---生成CLASS的命名规则 介绍了生成之类的命名规则, 在这个博文里面主要分析了下面3点:

1)Cglib如何生成的Class的二进制文件

2)Cglib生成的Class二进制(byte[])放哪

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

 

泛泛而谈,整个过程如下

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

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

 

 

1)Cglib如何生成的Class的二进制文件

针对不同场景, CGlib准备了不同的Class生成方法, 他们都实现了接口: ClassGenerator. 下面我们只针对默认的Enhancer来分析.

 

//此函数会被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

 

//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
分享到:
评论

相关推荐

    spring-cglib-repack-3.2.0.jar和spring-objenesis-repack-2.1.jar

    总的来说,`spring-cglib-repack-3.2.0.jar`和`spring-objenesis-repack-2.1.jar`是Spring框架正常运行的关键组成部分,它们分别负责动态子类生成和无参构造函数对象的快速实例化,对于理解和优化Spring应用的性能有...

    spring-cglib-repack-3.2.5.jar,spring-objenesis-repack-2.6.ja及ck-2.5.1.jar

    "spring-cglib-repack-3.2.5.jar"、"spring-objenesis-repack-2.6.jar"和"spring-objenesis-repack-2.5.1.jar"这三个文件是Spring源码阅读环境中常用的依赖包,它们各自承担着不同的功能。 首先,我们来看"CGLIB"...

    强势推送cglib-full-2.0及cglib-full-2.0.2

    在这里,我们有两个版本,即cglib-full-2.0和cglib-full-2.0.2。通常,更新的版本修复了旧版本中的bug,可能提供了新的特性和性能优化。从2.0到2.0.2,可能会包含一些稳定性改进和兼容性调整。 5. **使用步骤** -...

    spring-cglib-repack-3.2.4.jar和spring-objenesis-repack-2.5.1.jar

    当Spring框架在进行AOP代理时,如果目标类没有实现接口,它会选择使用CGLIB来创建一个子类并动态地插入拦截器方法。CGLIB通过字节码操作技术生成代理类,这样就可以在运行时扩展或修改已有类的功能,而无需修改原始...

    spring-cglib-repack-3.1.jar,spring-objenesis-repack-2.1.jar

    cglib-repack-3.1.jar"和"spring-objenesis-repack-2.1.jar"是Spring 4.0框架的重要组成部分,它们分别提供了动态子类生成和快速对象实例化的能力,对于理解Spring的内部机制,尤其是AOP和对象生命周期管理方面,...

    cglib-full-2.0.2.jar

    cglib-full-2.0.2.jar cglib-full-2.0.2.jar cglib-full-2.0.2.jar

    spring-cglib-repack-3.2.6.jar和spring-objenesis-repack-2.6.jar

    在提供的文件中,我们看到了两个与Spring相关的库:`spring-cglib-repack-3.2.6.jar` 和 `spring-objenesis-repack-2.6.jar`。这两个库都是Spring框架的重要组成部分,用于解决特定的编程问题。 首先,让我们来了解...

    spring-cglib-repack-3.2.5.jar,spring-objenesis-repack-2.6.jar

    标题中的"spring-cglib-repack-3.2.5.jar"和"spring-objenesis-repack-2.6.jar"是Spring框架在运行时依赖的两个关键库,它们主要涉及到动态代理和对象创建的优化。 1. **CGLIB(Code Generation Library)**: ...

    hibernate-cglib-repack-2.1_3.jar

    《深入理解Hibernate-CGLIB-2.1_3在Java开发中的应用》 在Java开发领域,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。而CGLIB则是一个代码生成库,它允许开发者在运行时动态创建子类...

    CGLIB需要的asm-2.2.3.jar和cglib-nodep-2.2.jar

    CGLIB-nodep-2.2.jar包含了CGLIB的所有核心类和接口,如Enhancer、MethodInterceptor等,用于实现动态代理和类的增强。 CGLIB的使用主要集中在以下几个方面: 1. **动态代理**:在Java中,如果我们想要在调用某个...

    cglib-nodep-3.2.4-API文档-中文版.zip

    赠送jar包:cglib-nodep-3.2.4.jar; 赠送原API文档:cglib-nodep-3.2.4-javadoc.jar; 赠送源代码:cglib-nodep-3.2.4-sources.jar; 赠送Maven依赖信息文件:cglib-nodep-3.2.4.pom; 包含翻译后的API文档:cglib-...

    spring-cglib-repack-3.2.5.jar spring-objenesis-repack-2.5.1.jar

    CGLIB通过生成子类并在子类的方法上插入拦截器来实现动态代理。"spring-cglib-repack-3.2.5.jar" 是CGLIB库的一个打包版本,重新打包是为了适应Spring框架的需求,可能包含了特定的修复或优化。 **2. Objenesis** ...

    Spring源码缺失的spring-cglib-repack-3.2.6.jar和spring-objenesis-repack-2.6.jar

    在Spring框架中,`spring-cglib-repack-3.2.6.jar`和`spring-objenesis-repack-2.6.jar`是两个重要的依赖库,它们在Spring源码环境中扮演着不可或缺的角色。本文将详细介绍这两个库以及它们在Spring框架中的作用。 ...

    spring导入eclipse时少的spring-cglib-repack-3.2.4.jar和spring-objenesis-repack-2.4.jar

    然而,有时候在导入Spring项目时,可能会遇到一些问题,例如标题中提到的"spring-cglib-repack-3.2.4.jar"和"spring-objenesis-repack-2.4.jar"这两个jar包的缺失。这些jar包对于Spring框架的正常运行至关重要,因为...

    spring-cglib-repack-3.2.0.jar

    spring-cglib-repack-3.2.0.jar是spring4.2.x以上版本的源码中,所必需的jar包。网上很难找到,在这里分享给大家

    cglib-3.1-API文档-中文版.zip

    赠送jar包:cglib-3.1.jar; 赠送原API文档:cglib-3.1-javadoc.jar; 赠送源代码:cglib-3.1-sources.jar; 赠送Maven依赖信息文件:cglib-3.1.pom; 包含翻译后的API文档:cglib-3.1-javadoc-API文档-中文(简体)版...

    spring-cglib-repack-3.2.0.jar和spring-objenesis-2.2.jar

    标题 "spring-cglib-repack-3.2.0.jar" 和 "spring-objenesis-2.2.jar" 指的是两个在Spring框架源代码构建过程中常用的库。这两个库在Spring框架的运行和开发中起着至关重要的作用。 首先,让我们详细了解一下...

    cglib-3.3.0-API文档-中文版.zip

    赠送jar包:cglib-3.3.0.jar; 赠送原API文档:cglib-3.3.0-javadoc.jar; 赠送源代码:cglib-3.3.0-sources.jar; 赠送Maven依赖信息文件:cglib-3.3.0.pom; 包含翻译后的API文档:cglib-3.3.0-javadoc-API文档-...

    spring-cglib-repack-3.2.11.jar+spring-objenesis-repack-3.0.jar 重新打包

    spring源码深度分析源码依赖,将cglib和objenesis重新打包处理。同时添加grandle依赖:compile fileTree(dir: 'libs', include: ['*.jar'])

Global site tag (gtag.js) - Google Analytics