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

CGLIB学习札记---生成CLASS的命名规则

 
阅读更多

CGLIB生存的Class的命名规则有多种,它们都是由接口NamingPolicy对应的实现来定义的.接下来针对DefaultNamingPolicy进行分析.泛泛的说,生成的CLASS的规则如下

 

被代理class name(包名和类名) + "$$" +

使用cglib处理的class name(只有类名,不包含包名) +"ByCGLIB" + "$$" +

key的hashcode(接下来会对key有一个详细的分析) +

序列号

 

下面是上面规则的示例:

aop.target.HelloImpl$$EnhancerByCGLIB$$494b5b61

aop.target.HelloImpl$$EnhancerByCGLIB$$494b5b61_2

aop.target.HelloImpl$$EnhancerByCGLIB$$494b5b61_3

 

下面是对应的关键代码

#DefaultNamingPolicy
public String getClassName(String prefix, String source, Object key, Predicate names) {
	
	
	StringBuffer sb = new StringBuffer();
	sb.append( 
			  (prefix != null) ? 
								 ( 
								  prefix.startsWith("java") ? 
											   "$" + prefix : prefix 
								 )
								: "net.sf.cglib.empty.Object"
			 );
	sb.append("$$");
	sb.append(source.substring(source.lastIndexOf('.') + 1));
	sb.append("ByCGLIB$$");
	sb.append(Integer.toHexString(key.hashCode()));
	String base = sb.toString();
	String attempt = base;
	int index = 2;
	while (names.evaluate(attempt)) {
		attempt = base + "_" + index++;
	}
   
	return attempt;
}

 

 

 Key 是什么?

上面的生成规则有4个参数,其中key是一个不太好理解的参数

Key是一个对象,该对象封装了下面7个信息. 并且这个Key对象是由Cglib生成的一个类来创建出来的.

1:superclass

2:interfaces

3:filter

4:callbackTypes

5:serialVersionUID

6:useFactory, 

7:interceptDuringConstruction

 

 下面的代码是生成key的接口定义,以及Cglib如何生成此接口的实例

//Enhancer.EnhancerKey 
    public interface EnhancerKey {
        public Object newInstance(String type,
                                  String[] interfaces,
                                  CallbackFilter filter,
                                  Type[] callbackTypes,
                                  boolean useFactory,
                                  boolean interceptDuringConstruction,
                                  Long serialVersionUID);
    }




//Enhancer Cglib会动态生成一个接口(EnhancerKey)的字节码并实例化,接下来将试用此对象生成Key来封装上面提到的几个参数
    private static final EnhancerKey KEY_FACTORY =
      (EnhancerKey)KeyFactory.create(EnhancerKey.class);
 

 

 

为什么有序列号的存在?

通常默认情况是,相同的Classload,相同的key只生成一个只生成一次子类并缓存,也就是在DefaultNamingPolicy,没有发现有序列号存在的可能. 序列号应该是在别的场景中使用. 下面是生成的子类是如何通过HashSet缓存起来的:

 

    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) {
                            byte[] b = strategy.generate(this);
                            String className = ClassNameReader.getClassName(new ClassReader(b));
                            //添加Classname到Cache里面, Cache实际上是一个HashSet的实例
                            getClassNameCache(loader).add(className);
                            gen = ReflectUtils.defineClass(className, b, loader);
                        }
                       
                        if (useCache) {
                            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);
        }
    }

 

 

 

接下来准备,继续写一个博文介绍下面3点

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

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

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

分享到:
评论
4 楼 lpf11230108 2014-07-09  
非常感谢lz的解答
3 楼 flyfoxs 2014-07-04  
http://git.eclipse.org/c/tmf/org.eclipse.xtext.git/plain/plugins/com.google.guice/src/com/google/inject/internal/BytecodeGen.java?id=198075462002121bc174119e3e706dfd2be7c820

http://zhouhaitao.iteye.com/blog/991365
2 楼 flyfoxs 2014-07-04  
lpf11230108 写道
有个问题想要请教lz 
prefix.startsWith("java") ? "$" + prefix : prefix
是否是为了防止和jdk中提供的类名冲突?


我觉得是的不是防止命名冲突,因为CGLIB代理Class,已经通过添加后缀的方式防止了命名冲突.

这个地方是因为以java开头的Package,是有特殊的安全检测机制的,所以需要重命名,来绕过去.
1 楼 lpf11230108 2014-07-03  
有个问题想要请教lz 
prefix.startsWith("java") ? "$" + prefix : prefix
是否是为了防止和jdk中提供的类名冲突?

相关推荐

    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"...

    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.4.jar和spring-objenesis-repack-2.5.1.jar

    在深入理解`spring-cglib-repack-3.2.4.jar`和`spring-objenesis-repack-2.5.1.jar`这两个jar包之前,我们先来了解一下Spring框架的核心概念。 Spring框架的核心包括依赖注入(Dependency Injection,DI)和面向切...

    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及cglib-full-2.0.2

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

    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)**: ...

    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-...

    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的一个无依赖版本,"nodep"即"no dependency"的缩写,意味着这个版本的CGLIB不包含任何外部依赖,只包含了CGLIB自身的核心功能。这对于那些希望减少项目依赖和减小应用体积的开发者来说...

    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包。网上很难找到,在这里分享给大家

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

    在本场景中,我们关注的是两个特定的jar包——"spring-cglib-repack-3.2.5.jar" 和 "spring-objenesis-repack-2.5.1.jar"。这些文件是Spring框架的组成部分,主要用于解决特定的依赖问题。 **1. CGLIB (Code ...

    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框架的运行和开发中起着至关重要的作用。 首先,让我们详细了解一下...

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

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

    spring-cglib-repack-3.2.8.jar

    spring查看源码所需要的jar包之一 spring-cglib-repack-3.2.8.jar

    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文档-...

Global site tag (gtag.js) - Google Analytics