7、cglib NamingPolicy 命名策略

背景

NamingPolicy表示生成類的名字的策略,比如、

上一節看到了生成的class文件名字是KeySample$MyFactory$$KeyFactoryByCGLIB$$7116a61e,這個是由NamingPolicy定的

結論

默認的實現類:DefaultNamingPolicy, 具體cglib動態生成類的命名控制

一般的命名規則:
被代理class name + "$$" + 使用cglib處理的class name + "ByCGLIB" + "$$" + key的hashcode
示例:FastSource$$FastClassByCGLIB$$e1a36bab.class

源碼

生成類的時候都會涉及AbstractClassGenerator#generateClass
都會生成類名,比如net.sf.cglib.core.KeyFactory.Generator#generateClass

ce.begin_class(Constants.V1_2,
                           Constants.ACC_PUBLIC,
                           getClassName(),
                           KEY_FACTORY,
                           new Type[]{ Type.getType(keyInterface) },
                           Constants.SOURCE_FILE);

AbstractClassGenerator#getClassName()是獲取類名

    final protected String getClassName() {
        if (className == null)
            className = getClassName(getClassLoader());
        return className;
    }
    
    private String getClassName(final ClassLoader loader) {
        final Set nameCache = getClassNameCache(loader);
        return namingPolicy.getClassName(namePrefix, source.name, key, new Predicate() {
            public boolean evaluate(Object arg) {
                return nameCache.contains(arg);
            }
        });
    }

NamingPolicy接口很簡單

public interface NamingPolicy {
    String getClassName(String prefix, String source, Object key, Predicate names);
    boolean equals(Object o);
}

默認的實現
net.sf.cglib.core.DefaultNamingPolicy#getClassName

public String getClassName(String prefix, String source, Object key, Predicate names) {
        if (prefix == null) {
            prefix = "net.sf.cglib.empty.Object";
        } else if (prefix.startsWith("java")) {
            prefix = "$" + prefix;
        }
        String base =
            prefix + "$$" + 
            source.substring(source.lastIndexOf('.') + 1) +
            getTag() + "$$" +
            Integer.toHexString(key.hashCode());
        String attempt = base;
        int index = 2;
        while (names.evaluate(attempt))
            attempt = base + "_" + index++;
        return attempt;
    }

其中prefix一般就是類名,比如samples.KeySample$MyFactory
source.substring(source.lastIndexOf('.') + 1) 就是source的按.最後一部分,如net.sf.cglib.core.KeyFactory截取KeyFactory
最後就是hashCode

思考

記住結論就行
被代理class name + "$$" + 使用cglib處理的class name + "ByCGLIB" + "$$" + key的hashcode

refer

http://cglib.sourceforge.net/apidocs/
http://www.cnblogs.com/cruze/p/3847968.html



轉摘:https://www.jianshu.com/p/dbaf90db1f8f

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章