cglib 动态代理
前言
cglib的源码实现要比JDK动态代理复杂的多,刚开始看会觉得很绕,其实只要把握住主线,明白总体的设计思路,看起来就会比较流程。
总体思路:整个过程就是围绕着AbstractClassGenerator和其子类进行。
- AbstractClassGenerator作为整个代理类的核心类,完成代理类对象实例的创建。
- 代理类本身的类创建动作由不同的AbstractClassGenerator子类来完成。
- cglib通过给原始类和代理类的所有方法标记索引值,达到避免反射调用的目的。
基本用法
public class CGLibProxy {
private Class> clazz;
public CGLibProxy(Class> clazz) {
this.clazz = clazz;
}
static {
// 用于输出生产代理类,源码查看用
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, ".");
}
public Object proxy() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(new CustomCallback());
Object o = enhancer.create();
return o;
}
public static void main(String[] args) {
SomeClass proxy = (SomeClass)new CGLibProxy(SomeClass.class).proxy();
proxy.doSomething();
}
}
class SomeClass {
public void doSomething() {
System.out.println("doSomething");
}
public void doOtherthing() {
System.out.println("doOtherthing");
}
}
class CustomCallback implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("增强");
Object invoke = methodProxy.invokeSuper(obj, args);
return invoke;
}
}
- 创建Enhancer对象
- 设置要扩展的类对象作为代理类的父类
- 设置回调类
- 回调类实现MethodInterceptor 扩展原方法功能
扩展用法
enhancer.setCallbacks(new Callback[] {new CustomCallback(), new CustomCallback2()});
enhancer.setCallbackFilter(new CustomCallbackFilter());
public class CustomCallbackFilter implements CallbackFilter {
@Override
public int accept(Method method) {
if (method.getName().contains("doSomething")) {
return 0;
} else if(method.getName().contains("doOtherthing")) {
return 1;
}
return 0;
}
}
设置回调过滤器,动态设置哪个方法用哪个Callback类的实现进行回调。
源码分析
Enhancer构造过程
Enhancer enhancer = new Enhancer();
cglib在初始化时就做了很多事情。
首先是Enhancer的构造过程:
public class Enhancer extends AbstractClassGenerator {
//定义默认的CallbackFilter, 且accept都设置为0
private static final CallbackFilter ALL_ZERO = new CallbackFilter(){
public int accept(Method method) {
return 0;
}
};
private static final Source SOURCE = new Source(Enhancer.class.getName());
// 这里构造了一个EnhancerKey,内部会生成cglib的一个代理类
// net.sf.cglib.proxy.Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72 详情见附录
private static final EnhancerKey KEY_FACTORY =
(EnhancerKey)KeyFactory.create(EnhancerKey.class, KeyFactory.HASH_ASM_TYPE, null);
KEY_FACTORY创建过程
先看下KEY_FACTORY的创建过程:
public static KeyFactory create(ClassLoader loader, Class keyInterface, KeyFactoryCustomizer customizer, List next) {
Generator gen = new Generator();
gen.setInterface(keyInterface);
if (customizer != null) {
gen.addCustomizer(customizer);
}
if (next != null && !next.isEmpty()) {
for (KeyFactoryCustomizer keyFactoryCustomizer : next) {
gen.addCustomizer(keyFactoryCustomizer);
}
}
gen.setClassLoader(loader);
return gen.create();
}
keyInterface是EnhancerKey.class, 设置类加载是keyInterface的classloader。最后调用gen.create()开始创建并加载这个Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72
。
public static class Generator extends AbstractClassGenerator {
// ...
public KeyFactory create() {
setNamePrefix(keyInterface.getName());
return (KeyFactory)super.create(keyInterface.getName());
}
这里的namePrefix就是net.sf.cglib.proxy.Enhancer$EnhancerKey
super.create是父类AbstractClassGenerator的实现。
abstract public class AbstractClassGenerator implements ClassGenerator {
// ...
protected Object create(Object key) {
try {
ClassLoader loader = getClassLoader();
Map cache = CACHE;
ClassLoaderData data = cache.get(loader);
if (data == null) {
synchronized (AbstractClassGenerator.class) {
cache = CACHE;
data = cache.get(loader);
if (data == null) {
Map newCache = new WeakHashMap(cache);
data = new ClassLoaderData(loader);
newCache.put(loader, data);
CACHE = newCache;
}
}
}
this.key = key;
Object obj = data.get(this, getUseCache());
if (obj instanceof Class) {
return firstInstance((Class) obj);
}
return nextInstance(obj);
} catch (RuntimeException e) {
throw e;
} catch (Error e) {
throw e;
} catch (Exception e) {
throw new CodeGenerationException(e);
}
}
protected static class ClassLoaderData {
public ClassLoaderData(ClassLoader classLoader) {
if (classLoader == null) {
throw new IllegalArgumentException("classLoader == null is not yet supported");
}
this.classLoader = new WeakReference(classLoader);
Function load =
new Function() {
public Object apply(AbstractClassGenerator gen) {
Class klass = gen.generate(ClassLoaderData.this);
return gen.wrapCachedClass(klass);
}
};
generatedClasses = new LoadingCache(GET_KEY, load);
}
private static final Function GET_KEY = new Function() {
public Object apply(AbstractClassGenerator gen) {
return gen.key;
}
};
第一部分是构造全局的Map
ClassLoaderData的构造方法定义了Function的load,并初始化了全局的generatedClasses。
第二部分就是通过data来生成代理类,入口是data.get(this, getUserCache()); 这里的catch默认是true。
public Object get(AbstractClassGenerator gen, boolean useCache) {
if (!useCache) {
return gen.generate(ClassLoaderData.this);
} else {
Object cachedValue = generatedClasses.get(gen);
return gen.unwrapCachedValue(cachedValue);
}
}
重点就是代理类的生成过程,由generatedClasses生成代理类class对象。
private static final Function GET_KEY = new Function() {
public Object apply(AbstractClassGenerator gen) {
// 这里的key是String类型的"net.sf.cglib.proxy.Enhancer$EnhancerKey"
return gen.key;
}
};
第一次缓存不存在,会调用createEntry。
protected V createEntry(final K key, KK cacheKey, Object v) {
FutureTask task;
boolean creator = false;
if (v != null) {
// Another thread is already loading an instance
task = (FutureTask) v;
} else {
task = new FutureTask(new Callable() {
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) prevTask;
} else {
return (V) prevTask;
}
}
V result;
try {
result = task.get();
} catch (InterruptedException e) {
...
}
if (creator) {
map.put(cacheKey, result);
}
return result;
}
这里最主要的call方法的调用,loader是
最终会调用到构造generatedClasses的load的Function的apply。
AbstractClassGenerator.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 {
gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain);
}
}
return gen;
} catch (RuntimeException e) {
throw e;
} catch (Error e) {
throw e;
} catch (Exception e) {
throw new CodeGenerationException(e);
} finally {
CURRENT.set(save);
}
}
这一段就是真正在完成各种代理类的构造过程,比如此时就是在生成net.sf.cglib.proxy.Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72
这个代理类
- 给代理类起名字
- 由不同的子类完成代理类的内容定义
- 类加载器load到jvm中
String name = generateClassName(data.getUniqueNamePredicate());
先给类起名字:三部分的拼接。
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(STRESS_HASH_CODE ? 0 : key.hashCode());
String attempt = base;
int index = 2;
while (names.evaluate(attempt))
attempt = base + "_" + index++;
return attempt;
}
byte[] b = strategy.generate(this); 这里的this是KeyFactory$Generator
public byte[] generate(ClassGenerator cg) throws Exception {
DebuggingClassWriter cw = getClassVisitor();
transform(cg).generateClass(cw);
return transform(cw.toByteArray());
}
按照默认的生成策略生成字节码,主要是利用ASM来生成字节码,内部用DebuggingClassWriter封装了一下,提供了可以输出字节码文件位置的扩展。本质还是通过ClassWriter来生成。最后返回字节码的字节数组。
其中,不同实现类的具体实现规则,由cg.generateClass(cw); 来完成。
下图可以看到很多的具体类型有不同字节码实现。
gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain);
通过反射调用类加载的defineClass方法来加载这个代理类。
public static Class defineClass(String className, byte[] b, ClassLoader loader, ProtectionDomain protectionDomain) throws Exception {
Class c;
if (DEFINE_CLASS != null) {
Object[] args = new Object[]{className, b, new Integer(0), new Integer(b.length), protectionDomain };
c = (Class)DEFINE_CLASS.invoke(loader, args);
} else if (DEFINE_CLASS_UNSAFE != null) {
Object[] args = new Object[]{className, b, new Integer(0), new Integer(b.length), loader, protectionDomain };
c = (Class)DEFINE_CLASS_UNSAFE.invoke(UNSAFE, args);
} else {
throw new CodeGenerationException(THROWABLE);
}
// Force static initializers to run.
Class.forName(className, true, loader);
return c;
}
最后返回代理类的class对象。
在上层会将这个代理类保证成WeakReference返回,并保存到LoadingCache的全局map中。key是字符串net.sf.cglib.proxy.Enhancer$EnhancerKey。
回到最上层的create方法,
Object obj = data.get(this, getUseCache());
if (obj instanceof Class) {
return firstInstance((Class) obj);
}
obj就是net.sf.cglib.proxy.Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72的class对象
调用firstInstance 创建实例对象,作为KEY_FACTORY。
至此,KEY_FACTORY 创建过程分析完成。
其他是定义各种的Type,将各种java语法和关键词转成ASM中的Type,用于后续的代理类定义。
Enhancer的构造方法主要完成的上述事情。
回调赋值
- 设置要扩展的原始类
- 设置回调的callback类,
- 可选回调filter,用于执行不同的方法运行不同的callback类。
enhancer.setSuperclass(clazz);
enhancer.setCallbacks(new Callback[] {new CustomCallback(), new CustomCallback2()});
enhancer.setCallbackFilter(new CustomCallbackFilter());
代理对象生成分析
enhancer.create(xxx);
public Object create() {
classOnly = false;
argumentTypes = null;
return createHelper();
}
public Object create(Class[] argumentTypes, Object[] arguments) {
classOnly = false;
if (argumentTypes == null || arguments == null || argumentTypes.length != arguments.length) {
throw new IllegalArgumentException("Arguments must be non-null and of equal length");
}
this.argumentTypes = argumentTypes;
this.arguments = arguments;
return createHelper();
}
create 有两个重载的方法,分别用于调用无参的构造方法和有参方法。最后统一调用createHelper();
private Object createHelper() {
preValidate();
Object key = KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,
ReflectUtils.getNames(interfaces),
filter == ALL_ZERO ? null : new WeakCacheKey(filter),
callbackTypes,
useFactory,
interceptDuringConstruction,
serialVersionUID);
this.currentKey = key;
Object result = super.create(key);
return result;
}
private void preValidate() {
if (callbackTypes == null) {
callbackTypes = CallbackInfo.determineTypes(callbacks, false);
validateCallbackTypes = true;
}
if (filter == null) {
if (callbackTypes.length > 1) {
throw new IllegalStateException("Multiple callback types possible but no filter specified");
}
filter = ALL_ZERO;
}
}
首先参数校验,且如果没有设置filter,默认ALL_ZERO。只调用第一个callback回调类。
接着,用上文创建出的代理类 net.sf.cglib.proxy.Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72
,调newInstance方法,实例化出一个Enhancer$EnhancerKey
的实例。Enhancer$EnhancerKeys
实例的属性保存了原始类的信息和设置的各种回调信息。具体参考附录1
有了这些信息,就可以基于此来创建子类实现。此时的this.currentKey=key=EnhancerKey的类对象。
super.create() 又回到AbstractClassGenerator的方法实现:
protected Object create(Object key) {
try {
ClassLoader loader = getClassLoader();
Map cache = CACHE;
ClassLoaderData data = cache.get(loader);
if (data == null) {
synchronized (AbstractClassGenerator.class) {
cache = CACHE;
data = cache.get(loader);
if (data == null) {
Map newCache = new WeakHashMap(cache);
data = new ClassLoaderData(loader);
newCache.put(loader, data);
CACHE = newCache;
}
}
}
this.key = key;
Object obj = data.get(this, getUseCache());
if (obj instanceof Class) {
return firstInstance((Class) obj);
}
return nextInstance(obj);
} catch (RuntimeException e) {
...
}
跟之前的区别是CACHE已经初始化过,直接看data.get(this, getUserCache()); 此时的this是Enhancer对象。
public Object get(AbstractClassGenerator gen, boolean useCache) {
if (!useCache) {
return gen.generate(ClassLoaderData.this);
} else {
Object cachedValue = generatedClasses.get(gen);
return gen.unwrapCachedValue(cachedValue);
}
}
整个过程跟之前的执行顺序一样,同样直接进入generatedClasses.get(gen);
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);
}
protected V createEntry(final K key, KK cacheKey, Object v) {
FutureTask task;
boolean creator = false;
if (v != null) {
// Another thread is already loading an instance
task = (FutureTask) v;
} else {
task = new FutureTask(new Callable() {
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) prevTask;
} else {
return (V) prevTask;
}
}
V result;
try {
result = task.get();
} catch (InterruptedException e) {
...
}
if (creator) {
map.put(cacheKey, result);
}
return result;
}
一样进入createEntry,因为此时的loader.apply(key); key是Enhancer对象,因此到此出现子类不同的generate实现。也就是Enhancer的实现。
Enhancer.generate()
protected Class generate(ClassLoaderData data) {
validate();
if (superclass != null) {
setNamePrefix(superclass.getName());
} else if (interfaces != null) {
setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName());
}
return super.generate(data);
}
同样先校验回调参数的正确性,在按照统一的命名规则来设置代理类的名称,一般格式为:
SomeClass$$EnhancerByCGLIB$$54d34479
回到父类的generate之后,调用过程同上,最后会继续调用子类(Enhancer)的generateClass(cw);
public void generateClass(ClassVisitor v) throws Exception {
Class sc = (superclass == null) ? Object.class : superclass;
if (TypeUtils.isFinal(sc.getModifiers()))
throw new IllegalArgumentException("Cannot subclass final class " + sc.getName());
List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors()));
filterConstructors(sc, constructors);
// Order is very important: must add superclass, then
// its superclass chain, then each interface and
// its superinterfaces.
List actualMethods = new ArrayList();
List interfaceMethods = new ArrayList();
final Set forcePublic = new HashSet();
getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic);
List methods = CollectionUtils.transform(actualMethods, new Transformer() {
public Object transform(Object value) {
Method method = (Method)value;
int modifiers = Constants.ACC_FINAL
| (method.getModifiers()
& ~Constants.ACC_ABSTRACT
& ~Constants.ACC_NATIVE
& ~Constants.ACC_SYNCHRONIZED);
if (forcePublic.contains(MethodWrapper.create(method))) {
modifiers = (modifiers & ~Constants.ACC_PROTECTED) | Constants.ACC_PUBLIC;
}
return ReflectUtils.getMethodInfo(method, modifiers);
}
});
// 后面还有很多生成字节码的代码
这里截取一部分,主要做的事情是将原始类的所有方法封装成MethodWrapper,(除了自定义的方法外,还有toString、equals、hashCode、clone这四个方法)。将这些方法结合ASM来生成代理类的class对象,跟上面过程一样,加载到jvm并缓存,缓存的key就是EnhancerKey里的所有参数,value就是class对象。代理类生成的代码参考附录2。
Object obj = data.get(this, getUseCache());
if (obj instanceof Class) {
return firstInstance((Class) obj);
}
代理类生成后,回到最上层的create方法,实例化代理对象,返回给业务代码。
MethodWrapper
private static final MethodWrapperKey KEY_FACTORY =
(MethodWrapperKey)KeyFactory.create(MethodWrapperKey.class);
MethodWrapper 也是cglib中的一个辅助类,内部封装了原始类的所有方法签名信息,同样是为了复用,生成过程也同样是由KeyFactory来创建,执行过程跟EnhancerKey的生成完全一样。生成后的代码参考附录3
Object o = enhancer.create();
至此,enhancer.create(); 代理类创建完成。到此会生成2个辅助类和1个业务代理类
Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72
辅助类:用于封装代理类的信息
MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7
辅助类:用于封装代理类的所有方法
SomeClass$$EnhancerByCGLIB$$1c48545c
业务类:真正的代理类
业务方法执行
SomeClass proxy = (SomeClass)new CGLibProxy(SomeClass.class).proxy();
proxy.doSomething();
既然是代理类,我们就要参考附录2的代理类代码
public final void doSomething() {
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$doSomething$0$Method, CGLIB$emptyArgs, CGLIB$doSomething$0$Proxy);
} else {
super.doSomething();
}
}
在构建这个doSomething的方法时,就已经指定好使用CALLBACK_0,也就是配置的第一个回调类,调用回调类的intercept方法。
intercept方法几个参数分别是代理类实例对象,Method类型的doSomething,doSomething方法参数,MethodProxy的对象。
其中需要着重看下MethodProxy的创建过程。
Method[] var10000 = ReflectUtils.findMethods(new String[]{"doSomething", "()V", "doOtherthing", "()V"}, (var1 = Class.forName("com.kuaishou.is.proxy.SomeClass")).getDeclaredMethods());
CGLIB$doSomething$0$Method = var10000[0];
CGLIB$doSomething$0$Proxy = MethodProxy.create(var1, var0, "()V", "doSomething", "CGLIB$doSomething$0");
MethodProxy.create
MethodProxy CGLIB$doSomething$0$Proxy = MethodProxy.create(var1, var0, "()V", "doSomething", "CGLIB$doSomething$0");
几个参数分别是代理类的类对象,原始类的类对象,doSomething的返回值类型,原始方法名,代理类生成的方法名。
需要说明的是,从附录2可以看到,代理类已经把原方法doSomething改成了调用intercepter,生成的代理方法调用super.doSomething,就是原方法本身。
public static MethodProxy create(Class c1, Class c2, String desc, String name1, String name2) {
MethodProxy proxy = new MethodProxy();
proxy.sig1 = new Signature(name1, desc);
proxy.sig2 = new Signature(name2, desc);
proxy.createInfo = new CreateInfo(c1, c2);
return proxy;
}
里面其实就是将这几个参数分别构建成几个类,sig1表示原始方法的签名,sig2表示代理类方法的签名,
private static class CreateInfo {
Class c1; //代理类
Class c2; // 原始类
NamingPolicy namingPolicy;
GeneratorStrategy strategy;
boolean attemptLoad;
public CreateInfo(Class c1, Class c2) {
this.c1 = c1;
this.c2 = c2;
AbstractClassGenerator fromEnhancer = AbstractClassGenerator.getCurrent();
if (fromEnhancer != null) {
namingPolicy = fromEnhancer.getNamingPolicy();
strategy = fromEnhancer.getStrategy();
attemptLoad = fromEnhancer.getAttemptLoad();
}
}
}
CreateInfo保存了两个类对象和代理类的生成策略。
此时回到自定义的MethodInterceptor实现类,根据调用过程我们知道,代理类最终会将调用引回到intercept方法上,intercept将是我们进行方法扩展的地方,扩展的方式一般是:前置扩展,原方法调用,后置扩展。
现在要说明此时要如何进行原方法的调用?
我们已经代理类的doSomething方法已经被改写,所以不能像jdk那样直接通过method.invoke调用,需要找到原始类的方法实现。
这里我们只能通过methodProxy来调用到原始方法,因为methodProxy已经存储了原始类和代理类,也存储了他们各自的方法。
methodProxy 提供了两个调用方法,invoke用于调用代理类的当前方法,invokeSuper用于调用原始类的当前方法。
public class CustomCallback implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("增强");
Object invoke = methodProxy.invokeSuper(obj, args);
// Object invoke = method.invoke(obj, args);
System.out.println("再增强");
return invoke;
}
}
看下invokeSuper的具体实现
MethodProxy.invokeSuper
private volatile FastClassInfo fastClassInfo;
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
try {
init();
FastClassInfo fci = fastClassInfo;
return fci.f2.invoke(fci.i2, obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
private void init() {
/*
* Using a volatile invariant allows us to initialize the FastClass and
* method index pairs atomically.
*
* Double-checked locking is safe with volatile in Java 5. Before 1.5 this
* code could allow fastClassInfo to be instantiated more than once, which
* appears to be benign.
*/
if (fastClassInfo == null) {
synchronized (initLock) {
if (fastClassInfo == null) {
CreateInfo ci = createInfo;
FastClassInfo fci = new FastClassInfo();
fci.f1 = helper(ci, ci.c1);
fci.f2 = helper(ci, ci.c2);
fci.i1 = fci.f1.getIndex(sig1);
fci.i2 = fci.f2.getIndex(sig2);
fastClassInfo = fci;
createInfo = null;
}
}
}
}
private static FastClass helper(CreateInfo ci, Class type) {
FastClass.Generator g = new FastClass.Generator();
g.setType(type);
g.setClassLoader(ci.c2.getClassLoader());
g.setNamingPolicy(ci.namingPolicy);
g.setStrategy(ci.strategy);
g.setAttemptLoad(ci.attemptLoad);
return g.create();
}
invokeSuper 调用分为以下几步:
- 通过double check来完成fastClassInfo全局变量的创建
- 创建过程中生成FastClass的辅助类
- 调用invoke完成原始类方法的调用
在调用helper方法时,会生成FastClass的辅助类,命名为com.kuaishou.is.proxy.SomeClass$$FastClassByCGLIB$$a7b28414
, 对应原始类的方法index
SomeClass$$EnhancerByCGLIB$$4ef3bf64$$FastClassByCGLIB$$87e87332.class
对应代理类的方法index
fc1.f1 和 fc1.f2 就是两个辅助类创建的实例对象。
其中FastClass的辅助类的生成还是之前的老套路,会生成一个
具体的实现是在FastClass的内部类Generator的generateClass方法
public void generateClass(ClassVisitor v) throws Exception {
new FastClassEmitter(v, getClassName(), type);
}
这个FastClassEmitter会根据传入的type也就是原始类class,基于此生成一系列方法内部实现,主要使用的方法就是getIndex,即给不同方法定义索引位置。参考附录4和5
后续通过getIndex方法来将i1和i2分别记录原始类和代理类中当前方法的索引值。
初始化完成后会调用invoke方法,
return fci.f2.invoke(fci.i2, obj, args);
f2是代理类对象, i2是代理后的方法索引值,obj是代理类实例对象。
可以知道其实是在调用代理类实例对象的代理方法,本质就是super.原方法。
至此完成原方法的调用。
这样做的目的就是通过给方法签名进行标记索引值,在调用时根据签名来找到方法,触发代理类的方法调用动作,避免出现反射动作。
总结
整体的执行过程分几部:
- 在Enhancer对象构建时,通过KeyFactory完成
Enhancer$EnhancerKey
的构建,Enhancer$EnhancerKey
用于封装原始类的各种信息及回调配置。 - enhancer.create(); 主要就是在完成代理类的结构定义
2.1 通过继承原始类,重写业务方法,改成内部调用回调类的invoke,开放扩展;
2.2 补充代理方法来完成super.原方法调用,即保留原方法调用;
2.3 将方法封装成MethodProxy,作为参数传递给invoke,提供外部扩展能力。 - invoke内的实现扩展的同时,调用MethodProxy.invokeSuper来调用原方法。
- MethodProxy封装了方法的实际调用,在内部定义了一个内部类FastClassInfo实现索引值查找方法,触发调用,避免反射。
- FastClass也会给每个原始类生成一个辅助类,记录方法和索引值的映射关系,在第一次调用业务方法时完成生成。
ps:
KeyFactory工厂定义不同的key的生成规则,每种key的职责不同,有不同的参数要求。同一种key通过不同的参数生成具体的代理类class对象,并将key参数和class对象一一对应缓存起来,实现复用的目的。
每种key有自己的generate方法,通过继承AbstractClassGenerator,在KeyFactory创建代理类class对象的过程中,调用自身实现的generate,并结合自身key的参数要求,(包括回调的设置),来基于asm生成代理类的字节码byte[],并封装成WeakReference缓存。
附录
因为的代码块不能折叠,所有代理类的代码都移到另一篇文章方便查看。动态代理实现源码剖析 —— 附录: cglib生成代理类