转载自:https://www.jianshu.com/p/ccd9
这里Enhancer类是CGLib中的一个字节码增强器,它可以方便的对你想要处理的类进行扩展
1.demo
拦截器1
package cglib; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class CglibProxy implements MethodInterceptor { //实现MethodInterceptor接口,定义方法的拦截器 @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("pre"); //通过代理类调用父类中的方法,即实体类方法 Object result = methodProxy.invokeSuper(o, objects); System.out.println("after"); return result; } }
拦截器2
package cglib; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class CglibProxy2 implements MethodInterceptor { //实现MethodInterceptor接口,定义方法的拦截器 @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("pre1"); //通过代理类调用父类中的方法,即实体类方法 Object result = methodProxy.invokeSuper(o, objects); System.out.println("after1"); return result; } }
回调过滤器CallbackFilter
package cglib; import net.sf.cglib.proxy.CallbackFilter; import java.lang.reflect.Method; public class filter implements CallbackFilter { @Override public int accept(Method method) { if(method.getName().equals("toString")) { return 1; } return 0; } }
测试类
package cglib; import net.sf.cglib.core.DebuggingClassWriter; import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.Enhancer; public class CglibLearn { //定义委托类,可以不是接口 static class serviceImpl { void say() { System.out.println("say"); } } public static Object getProxyInstance(Object realSubject) { Enhancer enhancer = new Enhancer(); //需要创建子类的类,即定义委托类 enhancer.setSuperclass(realSubject.getClass()); //设置两个CallBack以及CallbackFilter Callback[] callbacks=new Callback[2]; callbacks[0]=new CglibProxy(); callbacks[1]=new CglibProxy2(); enhancer.setCallbacks(callbacks); enhancer.setCallbackFilter(new filter()); //通过字节码技术动态创建子类实例 return enhancer.create(); } public static void main(String[] args) { //将sam,class文件写到硬盘 System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, ".//"); //通过生成子类的方式创建代理类 serviceImpl impl = (serviceImpl)getProxyInstance(new serviceImpl()); impl.say(); impl.toString(); } }
输出,自己想想就知道
2.源码分析
看源码之前,最好先了解下callBack和callBackFilter是有什么作用,再看会带着问题看
直接进测试类的enhancer.create();探究这个代理对象是怎么生成的,下面按照几个注意的环节来讲,会经历整个创建过程
2.1根据代理类的配置作为组合Key
net.sf.cglib.proxy.Enhancer#create() net.sf.cglib.proxy.Enhancer#createHelper() private Object createHelper() { //进行有效性验证,比如有多个callBack却没有callBackFilter validate(); if (superclass != null) { setNamePrefix(superclass.getName()); } else if (interfaces != null) { setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName()); } //先根据KEY_FACTORY 以当前代理类的配置信息 生成一个组合Key,再利用这个组合Key,进行create return super.create(KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null, ReflectUtils.getNames(interfaces), filter, callbackTypes, useFactory, interceptDuringConstruction, serialVersionUID)); }
private static final EnhancerKey KEY_FACTORY = (EnhancerKey)KeyFactory.create(EnhancerKey.class); public interface EnhancerKey { public Object newInstance(String type, String[] interfaces, CallbackFilter filter, Type[] callbackTypes, boolean useFactory, boolean interceptDuringConstruction, Long serialVersionUID); }
2.2 利用缓存完成根据Key获取Class信息,进而生成代理对象
这一块代码比较简单,和之前jdk动态代理利用的缓存差不多,在KeyFactory那一节也讲过,还是列出来就行,看注释就够了
protected Object create(Object key) { try { //需要缓存的类 Class gen = null; synchronized (source) { ClassLoader loader = getClassLoader(); Map cache2 = null; //根据来源区分,根据classLoader进行一级缓存 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)); getClassNameCache(loader).add(className); //根据字节码生成类 gen = ReflectUtils.defineClass(className, b, loader); } if (useCache) { //根据传入的key,进行二级缓存 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); } }
可以看出来,关注点集中在代理类的生成,即
byte[] b = strategy.generate(this);
2.3.代理类的生成
继续跟进
net.sf.cglib.core.GeneratorStrategy#generate net.sf.cglib.core.DefaultGeneratorStrategy#generate net.sf.cglib.core.ClassGenerator#generateClass net.sf.cglib.proxy.Enhancer#generateClass
最终就是利用Enhancer来生成代理类,下面有详细的注释
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); 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(); /* 根据规定的父类,生成需要的方法,参见 CglibLearn$serviceImpl$$EnhancerByCGLIB$$81852b18.class actualMethods记录所有经过过滤的方法 interfaceMethods和forcePublic的size都为0 */ getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic); for(int i=0;i
备注,上面利用asm完成类的生成,主要步骤如下
1.getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic);
这个方法就是递归的将superClass的父类,父接口的函数全部记录在method中,
然后过滤掉原有类的static方法,private方法,和superClass位于不同包的类中的方法(不知道何时会出现这种情况???),以及final方法
获取,并且过滤完之后,剩下的方法是
void cglib.CglibLearn$serviceImpl.say() protected void java.lang.Object.finalize() throws java.lang.Throwable public boolean java.lang.Object.equals(java.lang.Object) public java.lang.String java.lang.Object.toString() public native int java.lang.Object.hashCode() protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException
2.emitMethods
这个函数是用来生成代理类里面的methods,非常重要,列出源码如下
/* methods 是方法的信息列表, 每一个类型都是MethodInfo actualMethods 是真实的方法, 每一个类型都是Method */ private void emitMethods(final ClassEmitter ce, List methods, List actualMethods) { /* 根据callbackTypes得到对应的generator,跟进去看 比如callbackType是MethodInterceptor.class,对应的generator就是MethodInterceptorGenerator.INSTANCE */ CallbackGenerator[] generators = CallbackInfo.getGenerators(callbackTypes); Map groups = new HashMap(); final Map indexes = new HashMap(); final Map originalModifiers = new HashMap(); final Map positions = CollectionUtils.getIndexMap(methods); final Map declToBridge = new HashMap(); Iterator it1 = methods.iterator(); Iterator it2 = (actualMethods != null) ? actualMethods.iterator() : null; while (it1.hasNext()) { MethodInfo method = (MethodInfo)it1.next(); Method actualMethod = (it2 != null) ? (Method)it2.next() : null; /* 根据定义的callBackFilter的accept值,判断由哪一个callBack来过滤当前方法 filter这里默认是net.sf.cglib.proxy.Enhancer.ALL_ZERO,即accept永远返回0 */ int index = filter.accept(actualMethod); if (index >= callbackTypes.length) { throw new IllegalArgumentException("Callback filter returned an index that is too large: " + index); } originalModifiers.put(method, new Integer((actualMethod != null) ? actualMethod.getModifiers() : method.getModifiers())); //通过indexes这个map记录每个map该由第几个callBack来处理 indexes.put(method, new Integer(index)); //让这个callBack对应的generator 记录下来它要处理这个method List group = (List)groups.get(generators[index]); if (group == null) { groups.put(generators[index], group = new ArrayList(methods.size())); } group.add(method); // Optimization: build up a map of Class -> bridge methods in class // so that we can look up all the bridge methods in one pass for a class. if (TypeUtils.isBridge(actualMethod.getModifiers())) { Set bridges = (Set)declToBridge.get(actualMethod.getDeclaringClass()); if (bridges == null) { bridges = new HashSet(); declToBridge.put(actualMethod.getDeclaringClass(), bridges); } bridges.add(method.getSignature()); } } final Map bridgeToTarget = new BridgeMethodResolver(declToBridge).resolveAll(); Set seenGen = new HashSet(); CodeEmitter se = ce.getStaticHook(); se.new_instance(THREAD_LOCAL); se.dup(); se.invoke_constructor(THREAD_LOCAL, CSTRUCT_NULL); se.putfield(THREAD_CALLBACKS_FIELD); final Object[] state = new Object[1]; //下面context定义了如何根据callBack信息,来进行代码生成 CallbackGenerator.Context context = new CallbackGenerator.Context() { public ClassLoader getClassLoader() { return Enhancer.this.getClassLoader(); } public int getOriginalModifiers(MethodInfo method) { return ((Integer)originalModifiers.get(method)).intValue(); } //根据method判断对应的callBack下标 public int getIndex(MethodInfo method) { return ((Integer)indexes.get(method)).intValue(); } /* 根据下标让当前method生成“调用对应callBack”的代码 这也表现出来一个method只有一个callBack */ public void emitCallback(CodeEmitter e, int index) { emitCurrentCallback(e, index); } public Signature getImplSignature(MethodInfo method) { return rename(method.getSignature(), ((Integer)positions.get(method)).intValue()); } public void emitInvoke(CodeEmitter e, MethodInfo method) { // If this is a bridge and we know the target was called from invokespecial, // then we need to invoke_virtual w/ the bridge target instead of doing // a super, because super may itself be using super, which would bypass // any proxies on the target. Signature bridgeTarget = (Signature)bridgeToTarget.get(method.getSignature()); if (bridgeTarget != null) { // TODO: this assumes that the target has wider or the same type // parameters than the current. // In reality this should always be true because otherwise we wouldn't // have had a bridge doing an invokespecial. // If it isn't true, we would need to checkcast each argument // against the target's argument types e.invoke_virtual_this(bridgeTarget); Type retType = method.getSignature().getReturnType(); // Not necessary to cast if the target & bridge have // the same return type. // (This conveniently includes void and primitive types, // which would fail if casted. It's not possible to // covariant from boxed to unbox (or vice versa), so no having // to box/unbox for bridges). // TODO: It also isn't necessary to checkcast if the return is // assignable from the target. (This would happen if a subclass // used covariant returns to narrow the return type within a bridge // method.) if (!retType.equals(bridgeTarget.getReturnType())) { e.checkcast(retType); } } else { e.super_invoke(method.getSignature()); } } public CodeEmitter beginMethod(ClassEmitter ce, MethodInfo method) { CodeEmitter e = EmitUtils.begin_method(ce, method); if (!interceptDuringConstruction && !TypeUtils.isAbstract(method.getModifiers())) { Label constructed = e.make_label(); e.load_this(); e.getfield(CONSTRUCTED_FIELD); e.if_jump(e.NE, constructed); e.load_this(); e.load_args(); e.super_invoke(); e.return_value(); e.mark(constructed); } return e; } }; for (int i = 0; i < callbackTypes.length; i++) { CallbackGenerator gen = generators[i]; if (!seenGen.contains(gen)) { seenGen.add(gen); /* 每个callBack对应的generator要处理的列表为fmethods 下面将每个method对应的callBack调用关系,生成代码 */ final List fmethods = (List)groups.get(gen); if (fmethods != null) { try { gen.generate(ce, context, fmethods); gen.generateStatic(se, context, fmethods); } catch (RuntimeException x) { throw x; } catch (Exception x) { throw new CodeGenerationException(x); } } } } se.return_value(); se.end_method(); }
这里的主要工作如下
int index = filter.accept(actualMethod); 这里是判断当前method是由哪一个callBack来处理 ... 定义如何根据callBack信息,来进行代码生成 CallbackGenerator.Context context = new CallbackGenerator.Context(){xxx} ... 每个callBack对应的generator要处理的列表为fmethods 下面将每个method对应的callBack调用关系,生成代码 final List fmethods = (List)groups.get(gen);
2.4.代理类的结果
本地生成了文件

image.png
/* * Decompiled with CFR 0_118. * * Could not load the following classes: * cglib.CglibLearn * cglib.CglibLearn$serviceImpl * net.sf.cglib.core.ReflectUtils * net.sf.cglib.core.Signature * net.sf.cglib.proxy.Callback * net.sf.cglib.proxy.Factory * net.sf.cglib.proxy.MethodInterceptor * net.sf.cglib.proxy.MethodProxy */ package cglib; import cglib.CglibLearn; 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 CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b extends CglibLearn.serviceImpl implements Factory { private boolean CGLIB$BOUND; private static final ThreadLocal CGLIB$THREAD_CALLBACKS; private static final Callback[] CGLIB$STATIC_CALLBACKS; private MethodInterceptor CGLIB$CALLBACK_0; private MethodInterceptor CGLIB$CALLBACK_1; private static final Method CGLIB$say$0$Method; private static final MethodProxy CGLIB$say$0$Proxy; private static final Object[] CGLIB$emptyArgs; private static final Method CGLIB$finalize$1$Method; private static final MethodProxy CGLIB$finalize$1$Proxy; private static final Method CGLIB$equals$2$Method; private static final MethodProxy CGLIB$equals$2$Proxy; private static final Method CGLIB$toString$3$Method; private static final MethodProxy CGLIB$toString$3$Proxy; private static final Method CGLIB$hashCode$4$Method; private static final MethodProxy CGLIB$hashCode$4$Proxy; private static final Method CGLIB$clone$5$Method; private static final MethodProxy CGLIB$clone$5$Proxy; static void CGLIB$STATICHOOK1() { CGLIB$THREAD_CALLBACKS = new ThreadLocal(); CGLIB$emptyArgs = new Object[0]; Class class_ = Class.forName("cglib.CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b"); Class class_2 = Class.forName("java.lang.Object"); Method[] arrmethod = ReflectUtils.findMethods((String[])new String[]{"finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (Method[])class_2.getDeclaredMethods()); CGLIB$finalize$1$Method = arrmethod[0]; CGLIB$finalize$1$Proxy = MethodProxy.create(class_2, class_, (String)"()V", (String)"finalize", (String)"CGLIB$finalize$1"); CGLIB$equals$2$Method = arrmethod[1]; CGLIB$equals$2$Proxy = MethodProxy.create(class_2, class_, (String)"(Ljava/lang/Object;)Z", (String)"equals", (String)"CGLIB$equals$2"); CGLIB$toString$3$Method = arrmethod[2]; CGLIB$toString$3$Proxy = MethodProxy.create(class_2, class_, (String)"()Ljava/lang/String;", (String)"toString", (String)"CGLIB$toString$3"); CGLIB$hashCode$4$Method = arrmethod[3]; CGLIB$hashCode$4$Proxy = MethodProxy.create(class_2, class_, (String)"()I", (String)"hashCode", (String)"CGLIB$hashCode$4"); CGLIB$clone$5$Method = arrmethod[4]; CGLIB$clone$5$Proxy = MethodProxy.create(class_2, class_, (String)"()Ljava/lang/Object;", (String)"clone", (String)"CGLIB$clone$5"); class_2 = Class.forName("cglib.CglibLearn$serviceImpl"); CGLIB$say$0$Method = ReflectUtils.findMethods((String[])new String[]{"say", "()V"}, (Method[])class_2.getDeclaredMethods())[0]; CGLIB$say$0$Proxy = MethodProxy.create(class_2, class_, (String)"()V", (String)"say", (String)"CGLIB$say$0"); } final void CGLIB$say$0() { super.say(); } final void say() { MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0; if (methodInterceptor == null) { CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)this); methodInterceptor = this.CGLIB$CALLBACK_0; } if (methodInterceptor != null) { Object object = methodInterceptor.intercept((Object)this, CGLIB$say$0$Method, CGLIB$emptyArgs, CGLIB$say$0$Proxy); return; } super.say(); } final void CGLIB$finalize$1() throws Throwable { super.finalize(); } protected final void finalize() throws Throwable { MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0; if (methodInterceptor == null) { CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)this); methodInterceptor = this.CGLIB$CALLBACK_0; } if (methodInterceptor != null) { Object object = methodInterceptor.intercept((Object)this, CGLIB$finalize$1$Method, CGLIB$emptyArgs, CGLIB$finalize$1$Proxy); return; } super.finalize(); } final boolean CGLIB$equals$2(Object object) { return super.equals(object); } public final boolean equals(Object object) { MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0; if (methodInterceptor == null) { CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)this); methodInterceptor = this.CGLIB$CALLBACK_0; } if (methodInterceptor != null) { Object object2 = methodInterceptor.intercept((Object)this, CGLIB$equals$2$Method, new Object[]{object}, CGLIB$equals$2$Proxy); return object2 == null ? false : (Boolean)object2; } return super.equals(object); } final String CGLIB$toString$3() { return super.toString(); } public final String toString() { MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_1; if (methodInterceptor == null) { CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)this); methodInterceptor = this.CGLIB$CALLBACK_1; } if (methodInterceptor != null) { return (String)methodInterceptor.intercept((Object)this, CGLIB$toString$3$Method, CGLIB$emptyArgs, CGLIB$toString$3$Proxy); } return super.toString(); } final int CGLIB$hashCode$4() { return super.hashCode(); } public final int hashCode() { MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0; if (methodInterceptor == null) { CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)this); methodInterceptor = this.CGLIB$CALLBACK_0; } if (methodInterceptor != null) { Object object = methodInterceptor.intercept((Object)this, CGLIB$hashCode$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy); return object == null ? 0 : ((Number)object).intValue(); } return super.hashCode(); } final Object CGLIB$clone$5() throws CloneNotSupportedException { return super.clone(); } protected final Object clone() throws CloneNotSupportedException { MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0; if (methodInterceptor == null) { CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)this); methodInterceptor = this.CGLIB$CALLBACK_0; } if (methodInterceptor != null) { return methodInterceptor.intercept((Object)this, CGLIB$clone$5$Method, CGLIB$emptyArgs, CGLIB$clone$5$Proxy); } return super.clone(); } public static MethodProxy CGLIB$findMethodProxy(Signature signature) { String string = signature.toString(); switch (string.hashCode()) { case -: { if (!string.equals("finalize()V")) break; return CGLIB$finalize$1$Proxy; } case -: { if (!string.equals("say()V")) break; return CGLIB$say$0$Proxy; } case -: { if (!string.equals("clone()Ljava/lang/Object;")) break; return CGLIB$clone$5$Proxy; } case : { if (!string.equals("equals(Ljava/lang/Object;)Z")) break; return CGLIB$equals$2$Proxy; } case : { if (!string.equals("toString()Ljava/lang/String;")) break; return CGLIB$toString$3$Proxy; } case : { if (!string.equals("hashCode()I")) break; return CGLIB$hashCode$4$Proxy; } } return null; } public CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b() { CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b = this; CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b); } public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] arrcallback) { CGLIB$THREAD_CALLBACKS.set(arrcallback); } public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] arrcallback) { CGLIB$STATIC_CALLBACKS = arrcallback; } private static final void CGLIB$BIND_CALLBACKS(Object object) { CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b = (CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b)((Object)object); if (!cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BOUND) { cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BOUND = true; Object t = CGLIB$THREAD_CALLBACKS.get(); if (t != null || (v312 = CGLIB$STATIC_CALLBACKS) != null) { Callback[] arrcallback = (Callback[])t; CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b2 = cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b; cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b2.CGLIB$CALLBACK_1 = (MethodInterceptor)arrcallback[1]; cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b2.CGLIB$CALLBACK_0 = (MethodInterceptor)arrcallback[0]; } } } public Object newInstance(Callback[] arrcallback) { CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$SET_THREAD_CALLBACKS(arrcallback); CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$SET_THREAD_CALLBACKS(null); return new CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b(); } public Object newInstance(Callback callback) { throw new IllegalStateException("More than one callback object required"); } /* * Unable to fully structure code * Enabled aggressive block sorting * Lifted jumps to return sites */ public Object newInstance(Class[] var1_1, Object[] var2_2, Callback[] var3_3) { CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$SET_THREAD_CALLBACKS(var3_3); switch (var1_1.length) { case 0: { break; } } throw new IllegalArgumentException("Constructor not found"); lbl6: // 1 sources: CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$SET_THREAD_CALLBACKS(null); return new CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b(); } public Callback getCallback(int n) { MethodInterceptor methodInterceptor; CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)this); CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b = this; switch (n) { case 0: { methodInterceptor = cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$CALLBACK_0; break; } case 1: { methodInterceptor = cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$CALLBACK_1; break; } default: { methodInterceptor = null; } } return methodInterceptor; } public void setCallback(int n, Callback callback) { switch (n) { case 0: { this.CGLIB$CALLBACK_0 = (MethodInterceptor)callback; break; } case 1: { this.CGLIB$CALLBACK_1 = (MethodInterceptor)callback; break; } } } public Callback[] getCallbacks() { CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)this); CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b = this; return new Callback[]{this.CGLIB$CALLBACK_0, this.CGLIB$CALLBACK_1}; } public void setCallbacks(Callback[] arrcallback) { Callback[] arrcallback2 = arrcallback; this.CGLIB$CALLBACK_0 = (MethodInterceptor)arrcallback2[0]; Callback[] arrcallback3 = arrcallback2; CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b = this; this.CGLIB$CALLBACK_1 = (MethodInterceptor)arrcallback2[1]; } static { CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$STATICHOOK1(); } }
3.测试类的结果分析
参照上面得到的decompile文件
final void say() { MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0; if (methodInterceptor == null) { CGLIB$BIND_CALLBACKS(this); methodInterceptor = this.CGLIB$CALLBACK_0; } if (methodInterceptor != null) { methodInterceptor.intercept(this, CGLIB$say$0$Method, CGLIB$emptyArgs, CGLIB$say$0$Proxy); } else { say(); } }

image.png
这里就是CGLIB$CALLBACK_1了,这个是怎么办到的?
其实在之前讲net.sf.cglib.proxy.Enhancer#emitMethods时候就说了
context.emitCallback(e, context.getIndex(method));
完成了每个method知道自己对应的callBack是第几个
另外,拦截器拦截时,
Object result = methodProxy.invokeSuper(o, objects);
invokeSuper是干吗的
这在下一节FastClass会讲
4.思考
4.1 CallbackFilter 和 CallBack有什么关系
4.2 method与callBack之间的对应的关系是如何实现的
context.emitCallback(e, context.getIndex(method));
将这种对应关系写到类中去
4.3 Enhancer如何根据callBack,callBackFilter完成代理类class文件的定义
4.4 与jdk动态代理区别
这里cglib底层是用的asm,而jdk动态代理没有
4.5 Enhancer的"enhance"体现在哪
methodInterceptor.intercept(this, CGLIB$say$0$Method, CGLIB$emptyArgs, CGLIB$say$0$Proxy); //其中 CGLIB$say$0$Proxy = MethodProxy.create(cls2, cls, "()V", "say", "CGLIB$say$0");
最终将cls2的say方法转发给cls的CGLIB$say$0方法(并不是上文列出来的CGLIB$say$0),这个和fastClass相关,下一节再讲。
4.6 CGLIB$STATICHOOK1()作用
创建各种方法代理即MethodProxy,在下一节和fastClass一起讲
5.备注
net.sf.cglib.proxy.Enhancer#generateClass还有一些emit其他细节,目前没有涉及到,没有看
6.问题
findMethodProxy作用是啥,没有看到调用
7.refer
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/227891.html原文链接:https://javaforall.net
