1. 图解

上图主要描述了Cglib动态代理的主要执行过程,下面做详细分析,以下源码使用的Cglib版本为3.2.12。

2. Enhancer源码分析

public Object create() {
// 判断是否需要创建对象,false表示需要创建对象
classOnly = false;
// 使用的是无参构造函数,参数为null
argumentTypes = null;
// 创建动态代理class的方法
return createHelper();
} ...//此处省略 private Object createHelper() {
// 检查CallBack的类型是否符合要求
preValidate();
// 创建唯一标识
Object key = KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,
ReflectUtils.getNames(interfaces),
filter == ALL_ZERO ? null : new WeakCacheKey<CallbackFilter>(filter),
callbackTypes,
useFactory,
interceptDuringConstruction,
serialVersionUID);
this.currentKey = key;
// 调用父类创建对象
Object result = super.create(key);
return result;
}

使用唯一标识key,用来创建生成唯一的动态代理类,然后将创建的工作委托给父类进行,下面分析父类AbstractClassGenerator的create方法。

3. AbstractClassGenerator源码分析

   protected Object create(Object key) {
try {
// 获取类加载器
ClassLoader loader = getClassLoader();
// 应用缓存,其中key为类加载器,value通过该classloader加载的动态代理类
Map<ClassLoader, ClassLoaderData> cache = CACHE;
ClassLoaderData data = cache.get(loader);
if (data == null) {
synchronized (AbstractClassGenerator.class) {
cache = CACHE;
data = cache.get(loader);
if (data == null) {
Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
data = new ClassLoaderData(loader);
newCache.put(loader, data);
CACHE = newCache;
}
}
}
this.key = key;
// 获取缓存对象
Object obj = data.get(this, getUseCache());
// 如果返回的是Class对象,则创建一个该Class类的实例
if (obj instanceof Class) {
return firstInstance((Class) obj);
}
// 如果从缓存获取的是EnhancerFactoryData对象,那么说明已经存在一个相应的动态代理Class对象
return nextInstance(obj);
} catch (RuntimeException e) {
throw e;
} catch (Error e) {
throw e;
} catch (Exception e) {
throw new CodeGenerationException(e);
}
}

下面进入data.get()

public Object get(AbstractClassGenerator gen, boolean useCache) {
// 如果useCache为false,表示未使用缓存
if (!useCache) {
// 传入ClassLoaderData这个内部类的当前对象
return gen.generate(ClassLoaderData.this);
} else {
// 如果useCache为true,表示使用缓存
Object cachedValue = generatedClasses.get(gen);
return gen.unwrapCachedValue(cachedValue);
}
}

从源码可以看出,若未使用缓存,则调用gen.generate方法,若使用缓存调用generatedClasses.get。下面会依次分析,先分析gen.generate

    protected Class generate(ClassLoaderData data) {
Class gen;
Object save = CURRENT.get();
CURRENT.set(this);
try {
// 获取类加载
ClassLoader classLoader = data.getClassLoader();
if (classLoader == null) {
throw new IllegalStateException("ClassLoader is null while trying to define class " +
getClassName() + ". It seems that the loader has been expired from a weak reference somehow. " +
"Please file an issue at cglib's issue tracker.");
}
synchronized (classLoader) {
// 生成动态代理类的类名
String name = generateClassName(data.getUniqueNamePredicate());
data.reserveName(name);
this.setClassName(name);
}
if (attemptLoad) {
try {
gen = classLoader.loadClass(getClassName());
return gen;
} catch (ClassNotFoundException e) {
// ignore
}
}
// 使用策略模式生成字节码
byte[] b = strategy.generate(this);
// 获取生成的动态代理类的类名
String className = ClassNameReader.getClassName(new ClassReader(b));
ProtectionDomain protectionDomain = getProtectionDomain();
synchronized (classLoader) { // just in case
if (protectionDomain == null) {
gen = ReflectUtils.defineClass(className, b, classLoader);
} else {
// 通过classloader加载类字节码,返回一个Class对象
gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain);
}
}
// 返回生成的Class对象
return gen;
} catch (RuntimeException e) {
throw e;
} catch (Error e) {
throw e;
} catch (Exception e) {
throw new CodeGenerationException(e);
} finally {
CURRENT.set(save);
}
}

上面代码中有个核心方法,strategy.generate,默认会进入DefaultGeneratorStrategy的generate方法

    public byte[] generate(ClassGenerator cg) throws Exception {
// 获取ClassWriter
DebuggingClassWriter cw = getClassVisitor();
// 通过ClassWriter,生成一个代理类的Class文件
transform(cg).generateClass(cw);
// 将代理类的Class文件转换成字节数组
return transform(cw.toByteArray());
}

上述代码中,generateClass方法生成Class文件是底层核心实现,通过ASM框架,完成类的Class对象的组装,默认走KeyFactory类的generateClass。

      public void generateClass(ClassVisitor v) {
ClassEmitter ce = new ClassEmitter(v); Method newInstance = ReflectUtils.findNewInstance(keyInterface);
if (!newInstance.getReturnType().equals(Object.class)) {
throw new IllegalArgumentException("newInstance method must return Object");
} Type[] parameterTypes = TypeUtils.getTypes(newInstance.getParameterTypes());
// 开始生成类的基本信息,包含Class版本号、访问权限、Class名字等
ce.begin_class(Constants.V1_2,
Constants.ACC_PUBLIC,
getClassName(),
KEY_FACTORY,
new Type[]{ Type.getType(keyInterface) },
Constants.SOURCE_FILE);
EmitUtils.null_constructor(ce);
EmitUtils.factory_method(ce, ReflectUtils.getSignature(newInstance)); int seed = 0;
// 生成代理类的方法
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC,
TypeUtils.parseConstructor(parameterTypes),
null);
e.load_this();
e.super_invoke_constructor();
e.load_this();
List<FieldTypeCustomizer> fieldTypeCustomizers = getCustomizers(FieldTypeCustomizer.class);
for (int i = 0; i < parameterTypes.length; i++) {
Type parameterType = parameterTypes[i];
Type fieldType = parameterType;
for (FieldTypeCustomizer customizer : fieldTypeCustomizers) {
fieldType = customizer.getOutType(i, fieldType);
}
seed += fieldType.hashCode();
ce.declare_field(Constants.ACC_PRIVATE | Constants.ACC_FINAL,
getFieldName(i),
fieldType,
null);
e.dup();
e.load_arg(i);
for (FieldTypeCustomizer customizer : fieldTypeCustomizers) {
customizer.customize(e, i, parameterType);
}
e.putfield(getFieldName(i));
}
e.return_value();
e.end_method(); // 生成代理类的hashcode方法
e = ce.begin_method(Constants.ACC_PUBLIC, HASH_CODE, null);
int hc = (constant != 0) ? constant : PRIMES[(int)(Math.abs(seed) % PRIMES.length)];
int hm = (multiplier != 0) ? multiplier : PRIMES[(int)(Math.abs(seed * 13) % PRIMES.length)];
e.push(hc);
for (int i = 0; i < parameterTypes.length; i++) {
e.load_this();
e.getfield(getFieldName(i));
EmitUtils.hash_code(e, parameterTypes[i], hm, customizers);
}
e.return_value();
e.end_method(); // 生成代理类的equals方法
e = ce.begin_method(Constants.ACC_PUBLIC, EQUALS, null);
Label fail = e.make_label();
e.load_arg(0);
e.instance_of_this();
e.if_jump(e.EQ, fail);
for (int i = 0; i < parameterTypes.length; i++) {
e.load_this();
e.getfield(getFieldName(i));
e.load_arg(0);
e.checkcast_this();
e.getfield(getFieldName(i));
EmitUtils.not_equals(e, parameterTypes[i], fail, customizers);
}
e.push(1);
e.return_value();
e.mark(fail);
e.push(0);
e.return_value();
e.end_method(); // 生成代理类的toString方法
e = ce.begin_method(Constants.ACC_PUBLIC, TO_STRING, null);
e.new_instance(Constants.TYPE_STRING_BUFFER);
e.dup();
e.invoke_constructor(Constants.TYPE_STRING_BUFFER);
for (int i = 0; i < parameterTypes.length; i++) {
if (i > 0) {
e.push(", ");
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_STRING);
}
e.load_this();
e.getfield(getFieldName(i));
EmitUtils.append_string(e, parameterTypes[i], EmitUtils.DEFAULT_DELIMITERS, customizers);
}
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, TO_STRING);
e.return_value();
e.end_method();
// 生成代理类结束
ce.end_class();
}

通过分析上述代码,得知代理类的Class字节码文件生成是由底层的ClassEmitter封装ASM框架完成的,关于ASM框架,将在下一讲继续深入,里面涉及到三种设计模式的具体应用。

如果使用缓存方式获取代理类的Class对象,会调用generatedClasses.get,进入方法会到LoadingCache中

    public V get(K key) {
final KK cacheKey = keyMapper.apply(key);
Object v = map.get(cacheKey);
if (v != null && !(v instanceof FutureTask)) {
return (V) v;
} return createEntry(key, cacheKey, v);
}

进入createEntry

 protected V createEntry(final K key, KK cacheKey, Object v) {
FutureTask<V> task;
boolean creator = false;
if (v != null) {
// Another thread is already loading an instance
task = (FutureTask<V>) v;
} else {
task = new FutureTask<V>(new Callable<V>() {
public V call() throws Exception {
return loader.apply(key);
}
});
Object prevTask = map.putIfAbsent(cacheKey, task);
if (prevTask == null) {
// creator does the load
creator = true;
task.run();
} else if (prevTask instanceof FutureTask) {
task = (FutureTask<V>) prevTask;
} else {
return (V) prevTask;
}
}

上面代码会调用task.run,进入线程loader.apply方法,最终进入AbstractClassGenerator的内部类ClassLoaderData的方法

       public ClassLoaderData(ClassLoader classLoader) {
if (classLoader == null) {
throw new IllegalArgumentException("classLoader == null is not yet supported");
}
this.classLoader = new WeakReference<ClassLoader>(classLoader);
Function<AbstractClassGenerator, Object> load =
new Function<AbstractClassGenerator, Object>() {
public Object apply(AbstractClassGenerator gen) {
Class klass = gen.generate(ClassLoaderData.this);
return gen.wrapCachedClass(klass);
}
};
generatedClasses = new LoadingCache<AbstractClassGenerator, Object, Object>(GET_KEY, load);
}

会发现,匿名内部类里面还是会调用上面代码分析过的gen.generate方法,最终通过字节码框架ASM生成Class对象。

3. 逐步调试解析

整个调试过程从【趣味设计模式系列】之【代理模式1-基本原理、实战及框架应用】中的CglibTest示例程序开始调试,下面调试过程会比较长,总共分三个阶段。

3.1 初始化Enhancer实例阶段



进入CglibProxy的createProxy方法,如下图



当执行到13行时,会初始化父类AbstractClassGenerator的静态常量值DEFAULT_USE_CACHE,该值默认为true,如下图



接着会初始化Enhancer的静态常量KEY_FACTORY,该值也是创建EnhancerKey对象的关键,如下图



随后进入KeyFactory的create方法



上述方法里面会调用gen.create



继续调用静态内部类Generator的create方法,接口名为interface net.sf.cglib.proxy.Enhancer$EnhancerKey



随后调用super.create,进入父类AbstractClassGenerator的create方法



再往下会优先从缓存取数据



进入data.get方法



默认useCache为true,会走else逻辑,随后会进入LoadingCache的get方法



上面代码34行,会执行createEntry,进入LoadingCache类52行的task线程中,61行线程执行run方法,会执行线程内部call的方法,调用loader.apply



再往下会走到AbstractClassGenerator的96行



进入generate方法



再走到320行,进入generateClassName方法,执行生成类名的方法



随后又回到AbstractClassGenerator,执行332行



进入默认字节码生成策略类DefaultGeneratorStrategy的generate方法



执行到25行,进入KeyFactory类的generatorClass方法



上述代码,从241行开始,通过ASM框架生成新的类



通过观察类名,ce下面的classinfo信息,看出生成类名为net.sf.cglib.proxy.Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72的类,



最后又回到AbstractClassGenerator类的296行,用生成的Class对象,通过反射生成上述类名为net.sf.cglib.proxy.Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72

实例

以上步骤都是在执行Enhancer enhancer = new Enhancer()这一步完成的,总结上述步骤,就是为创建的代理类生成一个唯一的key,该key又由KeyFactory生成,最终生成的key是类名为net.sf.cglib.proxy.Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72的类。

3.2 代理类生成阶段

下面继续调式,走到CglibProxy的18行,开始执行enhancer.create方法,真正创建代理类,见下图



进入Enhancer的create方法,执行到305行



再进入createHelper方法



发现key为之前生成的类名为net.sf.cglib.proxy.Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72的实例,属性里面包含若干属性对象,其中FIELD_0为com.wzj.cglib.Apple,FIELD_3为回调类型数组,数组里只有一个元素,值为Lnet/sf/cglib/proxy/MethodInterceptor,再往下继续走,480行会调用父类的create方法,进入又回到之前AbstractClassGenerator类的create方法



执行到294行,从缓存获取值



进入get方法



继续走else逻辑,再进入get方法,走入34行的createEntry方法



一直往下走,发现调试步骤与上述一致,中间省去部分步骤,走到代理类的默认命名策略,名字为com.wzj.cglib.Apple$$EnhancerByCGLIB$$3a0529f7



随后往下几步与上述一致,最终在生成类的Class文件时,与上述稍有不同,会走到Enhancer类的generateClass方法



继续往下走,569行有几句注释,执行顺序非常重要,必须先添加父类,以及它的父类链,然后每个接口以及父类接口,随后按照注释说明,到575行,执行getMethods方法,见下图



进入getMethods方法,执行到551行,进入MethodWrapper.createSet方法



首先会进入静态常量方法包装类的key对应类MethodWrapperKey的实例初始化,如下图



随后进入KeyFactory的create方法



往下221行,执行super.create方法



进入该方法,又会回到最初的AbstractClassGenerator的create方法,



再往下与上面调试过的过程类似,中间部分调试省略,最后生成代理类Class文件,如下图



最后回到AbstractClassGenerator类的298行,nextInstance生成代理类的实例



最终通过设置回调函数,并通过反射完成代理类的实例的初始化,如下图

3.3 代理类的方法执行阶段



进入自定义的intercept方法



进入invokeSuper方法



执行到init方法



进入init的74行



进入helper方法,执行121的create方法



进入create方法,回到AbstractClassGenerator的create方法



根据ci得到该方法的被代理类,代理类,分别生成FastClass的两个实例f1,f2,下图是f1的生成过程











同理,生成FastClass的实例f2





目的是计算被代理类与代理类各自的方法的索引,获取当前方法在f1,f2中的签名,得到一个index,可以根据index映射对应类的对应方法,因此方法名->签名->索引值,三者是一一对应关系。

init方法完成后,往下走到228行,这里通过调用代理类的索引值19对应的方法,取代反射

进入会走到被代理类的目标方法

至此,上面代理的全过程已经分析完毕。

4. FastClass源码解析

上述调试过程中,生成了两个FastClass的实例,分别是被代理类与代理类的在执行代理方法时创建,这里应用了一个懒加载的思想,也就是说,一开始并没有FastClass,只有当MethodProxy方法代理真正被请求的时候,被代理类的方法需要映射到代理类的方法时,为了避免过度使用反射,才生成了FastClass的实例,完成调用。

FastClass有两个主要方法,获取方法签名后的索引值,以及根据索引值调用方法,主要思想就是在为了避免方法调用时,过度使用反射造成调用慢的问题,下面是两个方法。

//方法签名后的索引值
abstract public int getIndex(Signature sig); //根据索引值调用方法
abstract public Object invoke(int index, Object obj, Object[] args)

示例程序跑完后会在项目的根目录下生成三个类,其中两个FastClass类,一个代理类,如图

Apple$$FastClassByCGLIB$$ca2d2eb9类是为了使用被代理类的方法索引而生成的

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package com.wzj.cglib; import java.lang.reflect.InvocationTargetException;
import net.sf.cglib.core.Signature;
import net.sf.cglib.reflect.FastClass; public class Apple$$FastClassByCGLIB$$ca2d2eb9 extends FastClass {
public Apple$$FastClassByCGLIB$$ca2d2eb9(Class var1) {
super(var1);
} public int getIndex(Signature var1) {
String var10000 = var1.toString();
switch(var10000.hashCode()) {
case -1596601914:
// 当方法为secKill时,索引为0
if (var10000.equals("secKill()V")) {
return 0;
}
break;
case 1826985398:
if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
return 1;
}
break;
case 1913648695:
if (var10000.equals("toString()Ljava/lang/String;")) {
return 2;
}
break;
case 1984935277:
if (var10000.equals("hashCode()I")) {
return 3;
}
} return -1;
} public int getIndex(String var1, Class[] var2) {
switch(var1.hashCode()) {
case -1776922004:
if (var1.equals("toString")) {
switch(var2.length) {
case 0:
return 2;
}
}
break;
case -1295482945:
if (var1.equals("equals")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("java.lang.Object")) {
return 1;
}
}
}
break;
case 147696667:
if (var1.equals("hashCode")) {
switch(var2.length) {
case 0:
return 3;
}
}
break;
case 1969019727:
if (var1.equals("secKill")) {
switch(var2.length) {
case 0:
return 0;
}
}
} return -1;
} public int getIndex(Class[] var1) {
switch(var1.length) {
case 0:
return 0;
default:
return -1;
}
} public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
Apple var10000 = (Apple)var2;
int var10001 = var1; try {
switch(var10001) {
case 0:
var10000.secKill();
return null;
case 1:
return new Boolean(var10000.equals(var3[0]));
case 2:
return var10000.toString();
case 3:
return new Integer(var10000.hashCode());
}
} catch (Throwable var4) {
throw new InvocationTargetException(var4);
} throw new IllegalArgumentException("Cannot find matching method/constructor");
} public Object newInstance(int var1, Object[] var2) throws InvocationTargetException {
Apple var10000 = new Apple;
Apple var10001 = var10000;
int var10002 = var1; try {
switch(var10002) {
case 0:
var10001.<init>();
return var10000;
}
} catch (Throwable var3) {
throw new InvocationTargetException(var3);
} throw new IllegalArgumentException("Cannot find matching method/constructor");
} public int getMaxIndex() {
return 3;
}
}

Apple$$EnhancerByCGLIB$$3a0529f7$$FastClassByCGLIB$$17333818类是为了使用代理类的方法索引而生成的,见下图

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package com.wzj.cglib; import com.wzj.cglib.Apple..EnhancerByCGLIB..3a0529f7;
import java.lang.reflect.InvocationTargetException;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.reflect.FastClass; public class Apple$$EnhancerByCGLIB$$3a0529f7$$FastClassByCGLIB$$17333818 extends FastClass {
public Apple$$EnhancerByCGLIB$$3a0529f7$$FastClassByCGLIB$$17333818(Class var1) {
super(var1);
} public int getIndex(Signature var1) {
String var10000 = var1.toString();
switch(var10000.hashCode()) {
case -2055565910:
if (var10000.equals("CGLIB$SET_THREAD_CALLBACKS([Lnet/sf/cglib/proxy/Callback;)V")) {
return 17;
}
break;
case -1882565338:
if (var10000.equals("CGLIB$equals$1(Ljava/lang/Object;)Z")) {
return 9;
}
break;
case -1596601914:
if (var10000.equals("secKill()V")) {
return 7;
}
break;
case -1457535688:
if (var10000.equals("CGLIB$STATICHOOK1()V")) {
return 14;
}
break;
case -1411842725:
if (var10000.equals("CGLIB$hashCode$3()I")) {
return 8;
}
break;
case -894172689:
if (var10000.equals("newInstance(Lnet/sf/cglib/proxy/Callback;)Ljava/lang/Object;")) {
return 6;
}
break;
case -623122092:
if (var10000.equals("CGLIB$findMethodProxy(Lnet/sf/cglib/core/Signature;)Lnet/sf/cglib/proxy/MethodProxy;")) {
return 20;
}
break;
case -508378822:
if (var10000.equals("clone()Ljava/lang/Object;")) {
return 3;
}
break;
case -419626537:
if (var10000.equals("setCallbacks([Lnet/sf/cglib/proxy/Callback;)V")) {
return 15;
}
break;
case -266769987:
if (var10000.equals("CGLIB$secKill$0()V")) {
return 12;
}
break;
case 560567118:
if (var10000.equals("setCallback(ILnet/sf/cglib/proxy/Callback;)V")) {
return 13;
}
break;
case 811063227:
if (var10000.equals("newInstance([Ljava/lang/Class;[Ljava/lang/Object;[Lnet/sf/cglib/proxy/Callback;)Ljava/lang/Object;")) {
return 5;
}
break;
case 973717575:
if (var10000.equals("getCallbacks()[Lnet/sf/cglib/proxy/Callback;")) {
return 18;
}
break;
case 1221173700:
if (var10000.equals("newInstance([Lnet/sf/cglib/proxy/Callback;)Ljava/lang/Object;")) {
return 4;
}
break;
case 1230699260:
if (var10000.equals("getCallback(I)Lnet/sf/cglib/proxy/Callback;")) {
return 19;
}
break;
case 1306468936:
if (var10000.equals("CGLIB$toString$2()Ljava/lang/String;")) {
return 11;
}
break;
case 1584330438:
if (var10000.equals("CGLIB$SET_STATIC_CALLBACKS([Lnet/sf/cglib/proxy/Callback;)V")) {
return 16;
}
break;
case 1800494055:
if (var10000.equals("CGLIB$clone$4()Ljava/lang/Object;")) {
return 10;
}
break;
case 1826985398:
if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
return 0;
}
break;
case 1913648695:
if (var10000.equals("toString()Ljava/lang/String;")) {
return 1;
}
break;
case 1984935277:
if (var10000.equals("hashCode()I")) {
return 2;
}
} return -1;
} public int getIndex(String var1, Class[] var2) {
switch(var1.hashCode()) {
case -1776922004:
if (var1.equals("toString")) {
switch(var2.length) {
case 0:
return 1;
}
}
break;
case -1295482945:
if (var1.equals("equals")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("java.lang.Object")) {
return 0;
}
}
}
break;
case -1053468136:
if (var1.equals("getCallbacks")) {
switch(var2.length) {
case 0:
return 18;
}
}
break;
case -124978609:
if (var1.equals("CGLIB$equals$1")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("java.lang.Object")) {
return 9;
}
}
}
break;
case -60403779:
if (var1.equals("CGLIB$SET_STATIC_CALLBACKS")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("[Lnet.sf.cglib.proxy.Callback;")) {
return 16;
}
}
}
break;
case -29025555:
if (var1.equals("CGLIB$hashCode$3")) {
switch(var2.length) {
case 0:
return 8;
}
}
break;
case 85179481:
if (var1.equals("CGLIB$SET_THREAD_CALLBACKS")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("[Lnet.sf.cglib.proxy.Callback;")) {
return 17;
}
}
}
break;
case 94756189:
if (var1.equals("clone")) {
switch(var2.length) {
case 0:
return 3;
}
}
break;
case 147696667:
if (var1.equals("hashCode")) {
switch(var2.length) {
case 0:
return 2;
}
}
break;
case 161998109:
if (var1.equals("CGLIB$STATICHOOK1")) {
switch(var2.length) {
case 0:
return 14;
}
}
break;
case 495524492:
if (var1.equals("setCallbacks")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("[Lnet.sf.cglib.proxy.Callback;")) {
return 15;
}
}
}
break;
case 1154623345:
if (var1.equals("CGLIB$findMethodProxy")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("net.sf.cglib.core.Signature")) {
return 20;
}
}
}
break;
case 1543336189:
if (var1.equals("CGLIB$toString$2")) {
switch(var2.length) {
case 0:
return 11;
}
}
break;
case 1811874389:
if (var1.equals("newInstance")) {
switch(var2.length) {
case 1:
String var10001 = var2[0].getName();
switch(var10001.hashCode()) {
case -845341380:
if (var10001.equals("net.sf.cglib.proxy.Callback")) {
return 6;
}
break;
case 1730110032:
if (var10001.equals("[Lnet.sf.cglib.proxy.Callback;")) {
return 4;
}
}
case 2:
default:
break;
case 3:
if (var2[0].getName().equals("[Ljava.lang.Class;") && var2[1].getName().equals("[Ljava.lang.Object;") && var2[2].getName().equals("[Lnet.sf.cglib.proxy.Callback;")) {
return 5;
}
}
}
break;
case 1817099975:
if (var1.equals("setCallback")) {
switch(var2.length) {
case 2:
if (var2[0].getName().equals("int") && var2[1].getName().equals("net.sf.cglib.proxy.Callback")) {
return 13;
}
}
}
break;
case 1905679803:
if (var1.equals("getCallback")) {
switch(var2.length) {
case 1:
if (var2[0].getName().equals("int")) {
return 19;
}
}
}
break;
case 1951977610:
if (var1.equals("CGLIB$clone$4")) {
switch(var2.length) {
case 0:
return 10;
}
}
break;
case 1969019727:
if (var1.equals("secKill")) {
switch(var2.length) {
case 0:
return 7;
}
}
break;
case 2019235512:
// 调用CGLIB$secKill$0()时,返回索引值12
if (var1.equals("CGLIB$secKill$0")) {
switch(var2.length) {
case 0:
return 12;
}
}
} return -1;
} public int getIndex(Class[] var1) {
switch(var1.length) {
case 0:
return 0;
default:
return -1;
}
} public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
3a0529f7 var10000 = (3a0529f7)var2;
int var10001 = var1; try {
switch(var10001) {
case 0:
return new Boolean(var10000.equals(var3[0]));
case 1:
return var10000.toString();
case 2:
return new Integer(var10000.hashCode());
case 3:
return var10000.clone();
case 4:
return var10000.newInstance((Callback[])var3[0]);
case 5:
return var10000.newInstance((Class[])var3[0], (Object[])var3[1], (Callback[])var3[2]);
case 6:
return var10000.newInstance((Callback)var3[0]);
case 7:
var10000.secKill();
return null;
case 8:
return new Integer(var10000.CGLIB$hashCode$3());
case 9:
return new Boolean(var10000.CGLIB$equals$1(var3[0]));
case 10:
return var10000.CGLIB$clone$4();
case 11:
return var10000.CGLIB$toString$2();
// 当计算index为12时,调用var10000.CGLIB$secKill$0()
case 12:
var10000.CGLIB$secKill$0();
return null;
case 13:
var10000.setCallback(((Number)var3[0]).intValue(), (Callback)var3[1]);
return null;
case 14:
3a0529f7.CGLIB$STATICHOOK1();
return null;
case 15:
var10000.setCallbacks((Callback[])var3[0]);
return null;
case 16:
3a0529f7.CGLIB$SET_STATIC_CALLBACKS((Callback[])var3[0]);
return null;
case 17:
3a0529f7.CGLIB$SET_THREAD_CALLBACKS((Callback[])var3[0]);
return null;
case 18:
return var10000.getCallbacks();
case 19:
return var10000.getCallback(((Number)var3[0]).intValue());
case 20:
return 3a0529f7.CGLIB$findMethodProxy((Signature)var3[0]);
}
} catch (Throwable var4) {
throw new InvocationTargetException(var4);
} throw new IllegalArgumentException("Cannot find matching method/constructor");
} public Object newInstance(int var1, Object[] var2) throws InvocationTargetException {
3a0529f7 var10000 = new 3a0529f7;
3a0529f7 var10001 = var10000;
int var10002 = var1; try {
switch(var10002) {
case 0:
var10001.<init>();
return var10000;
}
} catch (Throwable var3) {
throw new InvocationTargetException(var3);
} throw new IllegalArgumentException("Cannot find matching method/constructor");
} public int getMaxIndex() {
return 20;
}
}

代理类为Apple$$EnhancerByCGLIB$$3a0529f7,如下图,当下面的CGLIB$secKill$0方法被调用时,父类的super.secKill被执行

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package com.wzj.cglib; import java.lang.reflect.Method;
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; public class Apple$$EnhancerByCGLIB$$3a0529f7 extends Apple implements Factory {
private boolean CGLIB$BOUND;
public static Object CGLIB$FACTORY_DATA;
private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
private static final Callback[] CGLIB$STATIC_CALLBACKS;
private MethodInterceptor CGLIB$CALLBACK_0;
private static Object CGLIB$CALLBACK_FILTER;
private static final Method CGLIB$secKill$0$Method;
private static final MethodProxy CGLIB$secKill$0$Proxy;
private static final Object[] CGLIB$emptyArgs;
private static final Method CGLIB$equals$1$Method;
private static final MethodProxy CGLIB$equals$1$Proxy;
private static final Method CGLIB$toString$2$Method;
private static final MethodProxy CGLIB$toString$2$Proxy;
private static final Method CGLIB$hashCode$3$Method;
private static final MethodProxy CGLIB$hashCode$3$Proxy;
private static final Method CGLIB$clone$4$Method;
private static final MethodProxy CGLIB$clone$4$Proxy; static void CGLIB$STATICHOOK1() {
CGLIB$THREAD_CALLBACKS = new ThreadLocal();
CGLIB$emptyArgs = new Object[0];
Class var0 = Class.forName("com.wzj.cglib.Apple$$EnhancerByCGLIB$$3a0529f7");
Class var1;
CGLIB$secKill$0$Method = ReflectUtils.findMethods(new String[]{"secKill", "()V"}, (var1 = Class.forName("com.wzj.cglib.Apple")).getDeclaredMethods())[0];
CGLIB$secKill$0$Proxy = MethodProxy.create(var1, var0, "()V", "secKill", "CGLIB$secKill$0");
Method[] var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
CGLIB$equals$1$Method = var10000[0];
CGLIB$equals$1$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$1");
CGLIB$toString$2$Method = var10000[1];
CGLIB$toString$2$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$2");
CGLIB$hashCode$3$Method = var10000[2];
CGLIB$hashCode$3$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$3");
CGLIB$clone$4$Method = var10000[3];
CGLIB$clone$4$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$4");
} // 当CGLIB$secKill$0被执行,调用父类被代理的方法
final void CGLIB$secKill$0() {
super.secKill();
} // 当代理方法被执行,内部调用自定义intercept方法
public final void secKill() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
} if (var10000 != null) {
var10000.intercept(this, CGLIB$secKill$0$Method, CGLIB$emptyArgs, CGLIB$secKill$0$Proxy);
} else {
super.secKill();
}
} final boolean CGLIB$equals$1(Object var1) {
return super.equals(var1);
} public final boolean equals(Object var1) {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
} if (var10000 != null) {
Object var2 = var10000.intercept(this, CGLIB$equals$1$Method, new Object[]{var1}, CGLIB$equals$1$Proxy);
return var2 == null ? false : (Boolean)var2;
} else {
return super.equals(var1);
}
} final String CGLIB$toString$2() {
return super.toString();
} public final String toString() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
} return var10000 != null ? (String)var10000.intercept(this, CGLIB$toString$2$Method, CGLIB$emptyArgs, CGLIB$toString$2$Proxy) : super.toString();
} final int CGLIB$hashCode$3() {
return super.hashCode();
} public final int hashCode() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
} if (var10000 != null) {
Object var1 = var10000.intercept(this, CGLIB$hashCode$3$Method, CGLIB$emptyArgs, CGLIB$hashCode$3$Proxy);
return var1 == null ? 0 : ((Number)var1).intValue();
} else {
return super.hashCode();
}
} final Object CGLIB$clone$4() throws CloneNotSupportedException {
return super.clone();
} protected final Object clone() throws CloneNotSupportedException {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
} return var10000 != null ? var10000.intercept(this, CGLIB$clone$4$Method, CGLIB$emptyArgs, CGLIB$clone$4$Proxy) : super.clone();
} public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
String var10000 = var0.toString();
switch(var10000.hashCode()) {
case -1596601914:
if (var10000.equals("secKill()V")) {
return CGLIB$secKill$0$Proxy;
}
break;
case -508378822:
if (var10000.equals("clone()Ljava/lang/Object;")) {
return CGLIB$clone$4$Proxy;
}
break;
case 1826985398:
if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
return CGLIB$equals$1$Proxy;
}
break;
case 1913648695:
if (var10000.equals("toString()Ljava/lang/String;")) {
return CGLIB$toString$2$Proxy;
}
break;
case 1984935277:
if (var10000.equals("hashCode()I")) {
return CGLIB$hashCode$3$Proxy;
}
} return null;
} public Apple$$EnhancerByCGLIB$$3a0529f7() {
CGLIB$BIND_CALLBACKS(this);
} public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
CGLIB$THREAD_CALLBACKS.set(var0);
} public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) {
CGLIB$STATIC_CALLBACKS = var0;
} private static final void CGLIB$BIND_CALLBACKS(Object var0) {
Apple$$EnhancerByCGLIB$$3a0529f7 var1 = (Apple$$EnhancerByCGLIB$$3a0529f7)var0;
if (!var1.CGLIB$BOUND) {
var1.CGLIB$BOUND = true;
Object var10000 = CGLIB$THREAD_CALLBACKS.get();
if (var10000 == null) {
var10000 = CGLIB$STATIC_CALLBACKS;
if (var10000 == null) {
return;
}
} var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
} } public Object newInstance(Callback[] var1) {
CGLIB$SET_THREAD_CALLBACKS(var1);
Apple$$EnhancerByCGLIB$$3a0529f7 var10000 = new Apple$$EnhancerByCGLIB$$3a0529f7();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
} public Object newInstance(Callback var1) {
CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1});
Apple$$EnhancerByCGLIB$$3a0529f7 var10000 = new Apple$$EnhancerByCGLIB$$3a0529f7();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
} public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
CGLIB$SET_THREAD_CALLBACKS(var3);
Apple$$EnhancerByCGLIB$$3a0529f7 var10000 = new Apple$$EnhancerByCGLIB$$3a0529f7;
switch(var1.length) {
case 0:
var10000.<init>();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
default:
throw new IllegalArgumentException("Constructor not found");
}
} public Callback getCallback(int var1) {
CGLIB$BIND_CALLBACKS(this);
MethodInterceptor var10000;
switch(var1) {
case 0:
var10000 = this.CGLIB$CALLBACK_0;
break;
default:
var10000 = null;
} return var10000;
} public void setCallback(int var1, Callback var2) {
switch(var1) {
case 0:
this.CGLIB$CALLBACK_0 = (MethodInterceptor)var2;
default:
}
} public Callback[] getCallbacks() {
CGLIB$BIND_CALLBACKS(this);
return new Callback[]{this.CGLIB$CALLBACK_0};
} public void setCallbacks(Callback[] var1) {
this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0];
} static {
CGLIB$STATICHOOK1();
}
}

5. 总结

5.1 代理的执行的三个阶段

  • 第一阶段,生成唯一代理类需要唯一的key,key的生成又需要KeyFactory,第一阶段就是初始化KeyFactory与key;
  • 第二阶段,生成代理类,代理类中的方法通过方法代理一并生成,其中关键的步骤都是在AbstractClassGenerator中完成的,并在生成过程中默认使用缓存取代理,缓存没有,利用ASM框架生成;
  • 第三阶段,代理方法执行阶段,通过FastClass生成中间类,为目标方法的执行提供方便。

5.2 FastClass机制

  • 使用了懒加载思想,在执行代理方法阶段生成,而非一开始就生成;
  • 通过方法->签名->索引值的映射,直接根据最终的索引值调用代理类方法,而非通过反射,提高效率。

【趣味设计模式系列】之【代理模式3--Cglib动态代理源码解析】的更多相关文章

  1. 【趣味设计模式系列】之【代理模式2--JDK动态代理源码解析】

    1. 图解 上图主要描述了JDK动态代理的执行过程,下面做详细分析. 2. Proxy源码分析 上一篇,在使用JDK动态代理的时候,借助于Proxy类,使用newProxyInstance静态方法,创 ...

  2. 设计模式系列之代理模式(Proxy Pattern)——对象的间接访问

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  3. C#设计模式系列:代理模式(Proxy)

    代理模式提供了一个中介控制对某个对象的访问.现实生活中,我们可能会用支票在市场交易中用来代替现金,支票就是账户中资金的代理. 1.代理模式简介 1.1>.定义 代理模式(Proxy)定义:代理模 ...

  4. C#设计模式系列:代理模式(Proxy Pattren)

    一.引言 在软件开发过程中,有些对象有时候会由于网络或者其他的障碍,以至于不能够或者不能直接访问到这些对象,如果直接访问对象给系统带来不必要的复杂性,这时候可以在客户端和目标对象之间增加一层中间层,让 ...

  5. 代理模式之cglib动态代理

    上一篇博客说了实现InvocationHandler接口的jdk动态代理,还有一种实现动态代理的方式则是:通过继承的方式实现的cglib动态代理. 先在程序中导入cglib的包,cglib-nodep ...

  6. Spring代理模式(CGLIB动态代理模式)

    jdk动态代理和CGLIB动态代理 没什么太大的区别,CGLIB动态代理不需要接口,但是需要导入jar包. 房东出租房子的方法: package com.bjsxt.proxy2; public cl ...

  7. 动态代理学习(二)JDK动态代理源码分析

    上篇文章我们学习了如何自己实现一个动态代理,这篇文章我们从源码角度来分析下JDK的动态代理 先看一个Demo: public class MyInvocationHandler implements ...

  8. 设计模式之JDK动态代理源码分析

    这里查看JDK1.8.0_65的源码,通过debug学习JDK动态代理的实现原理 大概流程 1.为接口创建代理类的字节码文件 2.使用ClassLoader将字节码文件加载到JVM 3.创建代理类实例 ...

  9. Spring代理模式(jdk动态代理模式)

    有动态代理和静态代理: 静态代理就是普通的Java继承调用方法. Spring有俩种动态代理模式:jdk动态代理模式 和 CGLIB动态代理 jdk动态代理模式: 代码实现: 房东出租房子的方法(继承 ...

随机推荐

  1. logging日志基础示例

    import logging logger = logging.getLogger() # 获取日志对象 logfile = 'test.log' hdlr = logging.FileHandler ...

  2. 11-Pandas之排序(df.sort_index()、df.sort_values()、随机重排、随机采样)

    排序是一种索引机制的一种常见的操作方法,也是Pandas重要的内置运算,主要包括以下3种方法: 排序方法 说明 sort_values() 根据某一列的值进行排序 sort_index() 根据索引进 ...

  3. PHP ftruncate() 函数

    定义和用法 ftruncate() 函数把打开文件截断到指定的长度. 如果成功则返回 TRUE,如果失败则返回 FALSE. 语法 ftruncate(file,size) 参数 描述 file 必需 ...

  4. PHP rename() 函数

    定义和用法 rename() 函数重命名文件或目录. 如果成功,该函数返回 TRUE.如果失败,则返回 FALSE. 语法 rename(oldname,newname,context) 参数 描述 ...

  5. Blob分析之bottle.hdev

    * 分割读取啤酒瓶子上的数字* bottle.hdev: Segment and read numbers on a beer bottle* 第0步* Step 0: Preparations*定义 ...

  6. Swap常用操作与性能测试

    Swap分区通常被称为交换分区,这块儿分区位于硬盘的某个位置,当系统内存(物理内存)不够用的时候,如果开启了交换分区,部分内存里面暂时不用的数据就会Swap out(换出)到这块儿分区:当系统要使用这 ...

  7. 【python接口自动化】- logging日志模块

    前言:我们之前运行代码时都是将日志直接输出到控制台,而实际项目中常常需要把日志存储到文件,便于查阅,如运行时间.描述信息以及错误或者异常发生时候的特定上下文信息. logging模块介绍 ​ Pyth ...

  8. 精讲RestTemplate第3篇-GET请求使用方法详解

    本文是精讲RestTemplate第3篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用 精讲RestTemplate第2篇-多种底层H ...

  9. 为什么overflow:hidden能达到清除浮动的目的?

    1. 什么是浮动 <精通CSS>(第3版)关于浮动的描述: 浮动盒子可以向左或向右移动,直到其外边沿接触包含块的外边沿,或接触另一个浮动盒子的外边沿. 浮动盒子也会脱离常规文档流,因此常规 ...

  10. 【Spring注解驱动开发】使用@PropertySource加载配置文件,我只看这一篇!!

    写在前面 很多小伙伴都在问:冰河,你的Spring专题更新完了吗?怎么感觉像是写了一半啊?我:没有更新完呀,整个专题预计会有70多篇.那怎么更新了一半就去写别的了呢?那是因为有很多其他的小伙伴在后台留 ...