Java中Cglib代理类重写逻辑详解
作者:ps酷教程
这篇文章主要介绍了Java中Cglib代理类重写逻辑详解,代理类中只会维护NoOp这个回调属性,并不会生成目标类MyService中的noOp所对应的方法,需要的朋友可以参考下
前言
要看懂Spring Aop,必须先看懂不同cglib回调类型所应用的方法,在代理类中的重写逻辑。
引入包
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency>
Callback回调
Callback_NoOp
public class Callback_NoOp implements NoOp { }
Callback_MethodInterceptor
public class Callback_MethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("enter MethodInterceptor..."); return null; } }
Callback_LazyLoader
public class Callback_LazyLoader implements LazyLoader { @Override public Object loadObject() throws Exception { System.out.println("enter LazyLoader..."); return null; } }
Callback_InvocationHandler
public class Callback_InvocationHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("enter InvocationHandler..."); return null; } }
Callback_FixedValue
public class Callback_FixedValue implements FixedValue { @Override public Object loadObject() throws Exception { System.out.println("enter Callback_FixedValue..."); return null; } }
Callback_Dispatcher
public class Callback_Dispatcher implements Dispatcher { @Override public Object loadObject() throws Exception { System.out.println("enter Callback_Dispatcher..."); return null; } }
CustomizedCallbackFilter
public class CustomizedCallbackFilter implements CallbackFilter { @Override public int accept(Method method) { String methodName = method.getName(); switch (methodName) { case "noOp": return 0; case "methodInterceptor": return 1; case "lazyLoader": return 2; case "invocationHandler": return 3; case "fixedValue": return 4; case "dispatcher": return 5; } return 0; } }
MyService
目标类
public class MyService { public void noOp() { System.out.println("myService no op"); } public void methodInterceptor() { System.out.println("myService method interceptor"); } public void lazyLoader() { System.out.println("myService lazy loader"); } public void invocationHandler() { System.out.println("myService invocation handler"); } public void fixedValue() { System.out.println("myService fixed value"); } public void dispatcher() { System.out.println("myService dispatcher"); } }
Test01
public class Test01 { public static void main(String[] args) { System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\Projects\\learning\\proxy-dynamic-demo\\target\\classes"); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(MyService.class); Callback_NoOp callback_noOp = new Callback_NoOp(); Callback_MethodInterceptor callback_methodInterceptor = new Callback_MethodInterceptor(); Callback_LazyLoader callback_lazyLoader = new Callback_LazyLoader(); Callback_InvocationHandler callback_invocationHandler = new Callback_InvocationHandler(); Callback_FixedValue callback_fixedValue = new Callback_FixedValue(); Callback_Dispatcher callback_dispatcher = new Callback_Dispatcher(); enhancer.setCallbacks(new Callback[]{ callback_noOp, callback_methodInterceptor, callback_lazyLoader, callback_invocationHandler, callback_fixedValue, callback_dispatcher }); enhancer.setCallbackFilter(new CustomizedCallbackFilter()); Object enhancedObj = enhancer.create(); } }
结论
NoOp
代理类中只会维护NoOp这个回调属性,并不会生成目标类MyService中的noOp所对应的方法
MethodInterceptor
可见,代理类中生成了目标类MyService中的methodInterceptor方法所对应的 CGLIB$methodInterceptor$1 和 methodInterceptor方法 这种类型的回调最为常用,它里面利用了FastClass,这种FastClass建立了调用逻辑和方法签名和索引之间的映射关系,能够快速的根据索引找到所对应的调用逻辑。
final void CGLIB$methodInterceptor$1() { // 直接调用父类的methodInterceptor方法 super.methodInterceptor(); } public final void methodInterceptor() { // 获取绑定的回调对象 MethodInterceptor var10000 = this.CGLIB$CALLBACK_1; if (var10000 == null) { CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_1; } // 如果有设置的话(框架里面一般都设置了) if (var10000 != null) { // 第一个参数就是当前代理类对象this // 第二个参数是MyService的methodInterceptor方法 // 第三个参数是参数,因为这个方法没有参数,就用固定的这个CGLIB$emptyArgs,如果有参数的话,就会传入方法的参数 // 最后一个参数是MethodProxy类型的,它与FastClass机制的使用相关 var10000.intercept(this, CGLIB$methodInterceptor$1$Method, CGLIB$emptyArgs, CGLIB$methodInterceptor$1$Proxy); } else { super.methodInterceptor(); } }
LazyLoader
可见,代理类中生成了目标类MyService中的lazyLoader方法所对应的 lazyLoader 方法
public final void lazyLoader() { // 每次都会调用下面这个CGLIB$LOAD_PRIVATE_2()方法 ((MyService)this.CGLIB$LOAD_PRIVATE_2()).lazyLoader(); } private final synchronized Object CGLIB$LOAD_PRIVATE_2() { // 获取CGLIB$LAZY_LOADER_2属性,即绑定的回调对象 Object var10000 = this.CGLIB$LAZY_LOADER_2; // 如果从CGLIB$LAZY_LOADER_2属性获取的是null,则走下面逻辑 // 如果不为null,直接将结果返回,所以这种类型会将结果返回并保存, // 等下次调用,直接返回结果 // 也就是说这种类型的回调对象只会被调用 1 次 if (var10000 == null) { // 如果还未绑定 LazyLoader var10001 = this.CGLIB$CALLBACK_2; if (var10001 == null) { CGLIB$BIND_CALLBACKS(this); var10001 = this.CGLIB$CALLBACK_2; } // 调用回调对象的loadObject方法, // 并将调用结果返回作为方法的返回值 // 并将返回的结果设置给this.CGLIB$LAZY_LOADER_2属性 var10000 = this.CGLIB$LAZY_LOADER_2 = var10001.loadObject(); } // 返回调用结果或直接返回 return var10000; }
InvocationHandler
public final void invocationHandler() { try { // 获取绑定的回调对象CGLIB$CALLBACK_3 InvocationHandler var10000 = this.CGLIB$CALLBACK_3; if (var10000 == null) { CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_3; } // 直接调用回调对象的invoke方法,参数CGLIB$invocationHandler$0是MyService中的invocationHandler方法 var10000.invoke(this, CGLIB$invocationHandler$0, new Object[0]); } catch (Error | RuntimeException var1) { throw var1; } catch (Throwable var2) { throw new UndeclaredThrowableException(var2); } }
FixedValue
public final void fixedValue() { // 获取绑定的回调对象 FixedValue var10000 = this.CGLIB$CALLBACK_4; if (var10000 == null) { // 如果还未绑定 CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_4; } // 每次调用都会调用回调对象的loadObject方法 var10000.loadObject(); }
Dispatcher
public final void dispatcher() { // 获取绑定的回调对象 Dispatcher var10000 = this.CGLIB$CALLBACK_5; if (var10000 == null) { CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_5; } // 调用回调对象的loadObject方法,将返回的结果去调用dispatcher方法 ((MyService)var10000.loadObject()).dispatcher(); }
[Cglib生成的代理类]
package com.zzhua.cglib.service; 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.Dispatcher; import net.sf.cglib.proxy.Factory; import net.sf.cglib.proxy.FixedValue; import net.sf.cglib.proxy.InvocationHandler; import net.sf.cglib.proxy.LazyLoader; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import net.sf.cglib.proxy.NoOp; import net.sf.cglib.proxy.UndeclaredThrowableException; public class MyService$$EnhancerByCGLIB$$91e58a41 extends MyService implements Factory { private boolean CGLIB$BOUND; private static final ThreadLocal CGLIB$THREAD_CALLBACKS; private static final Callback[] CGLIB$STATIC_CALLBACKS; private NoOp CGLIB$CALLBACK_0; private MethodInterceptor CGLIB$CALLBACK_1; private LazyLoader CGLIB$CALLBACK_2; private InvocationHandler CGLIB$CALLBACK_3; private FixedValue CGLIB$CALLBACK_4; private Dispatcher CGLIB$CALLBACK_5; private static final Method CGLIB$methodInterceptor$1$Method; private static final MethodProxy CGLIB$methodInterceptor$1$Proxy; private static final Object[] CGLIB$emptyArgs; private Object CGLIB$LAZY_LOADER_2; private static final Method CGLIB$invocationHandler$0; static void CGLIB$STATICHOOK1() { CGLIB$THREAD_CALLBACKS = new ThreadLocal(); CGLIB$emptyArgs = new Object[0]; Class var0 = Class.forName("com.zzhua.cglib.service.MyService$$EnhancerByCGLIB$$91e58a41"); Class var1; CGLIB$methodInterceptor$1$Method = ReflectUtils.findMethods(new String[]{"methodInterceptor", "()V"}, (var1 = Class.forName("com.zzhua.cglib.service.MyService")).getDeclaredMethods())[0]; CGLIB$methodInterceptor$1$Proxy = MethodProxy.create(var1, var0, "()V", "methodInterceptor", "CGLIB$methodInterceptor$1"); CGLIB$invocationHandler$0 = Class.forName("com.zzhua.cglib.service.MyService").getDeclaredMethod("invocationHandler"); } final void CGLIB$methodInterceptor$1() { super.methodInterceptor(); } public final void methodInterceptor() { MethodInterceptor var10000 = this.CGLIB$CALLBACK_1; if (var10000 == null) { CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_1; } if (var10000 != null) { var10000.intercept(this, CGLIB$methodInterceptor$1$Method, CGLIB$emptyArgs, CGLIB$methodInterceptor$1$Proxy); } else { super.methodInterceptor(); } } public static MethodProxy CGLIB$findMethodProxy(Signature var0) { String var10000 = var0.toString(); switch(var10000.hashCode()) { case -1368021391: if (var10000.equals("methodInterceptor()V")) { return CGLIB$methodInterceptor$1$Proxy; } } return null; } public final void lazyLoader() { ((MyService)this.CGLIB$LOAD_PRIVATE_2()).lazyLoader(); } private final synchronized Object CGLIB$LOAD_PRIVATE_2() { Object var10000 = this.CGLIB$LAZY_LOADER_2; if (var10000 == null) { LazyLoader var10001 = this.CGLIB$CALLBACK_2; if (var10001 == null) { CGLIB$BIND_CALLBACKS(this); var10001 = this.CGLIB$CALLBACK_2; } var10000 = this.CGLIB$LAZY_LOADER_2 = var10001.loadObject(); } return var10000; } public final void invocationHandler() { try { InvocationHandler var10000 = this.CGLIB$CALLBACK_3; if (var10000 == null) { CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_3; } var10000.invoke(this, CGLIB$invocationHandler$0, new Object[0]); } catch (Error | RuntimeException var1) { throw var1; } catch (Throwable var2) { throw new UndeclaredThrowableException(var2); } } public final void fixedValue() { FixedValue var10000 = this.CGLIB$CALLBACK_4; if (var10000 == null) { CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_4; } var10000.loadObject(); } public final void dispatcher() { Dispatcher var10000 = this.CGLIB$CALLBACK_5; if (var10000 == null) { CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_5; } ((MyService)var10000.loadObject()).dispatcher(); } public MyService$$EnhancerByCGLIB$$91e58a41() { 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) { MyService$$EnhancerByCGLIB$$91e58a41 var1 = (MyService$$EnhancerByCGLIB$$91e58a41)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; } } Callback[] var10001 = (Callback[])var10000; var1.CGLIB$CALLBACK_5 = (Dispatcher)((Callback[])var10000)[5]; var1.CGLIB$CALLBACK_4 = (FixedValue)var10001[4]; var1.CGLIB$CALLBACK_3 = (InvocationHandler)var10001[3]; var1.CGLIB$CALLBACK_2 = (LazyLoader)var10001[2]; var1.CGLIB$CALLBACK_1 = (MethodInterceptor)var10001[1]; var1.CGLIB$CALLBACK_0 = (NoOp)var10001[0]; } } public Object newInstance(Callback[] var1) { CGLIB$SET_THREAD_CALLBACKS(var1); MyService$$EnhancerByCGLIB$$91e58a41 var10000 = new MyService$$EnhancerByCGLIB$$91e58a41(); CGLIB$SET_THREAD_CALLBACKS((Callback[])null); return var10000; } public Object newInstance(Callback var1) { throw new IllegalStateException("More than one callback object required"); } public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) { CGLIB$SET_THREAD_CALLBACKS(var3); MyService$$EnhancerByCGLIB$$91e58a41 var10000 = new MyService$$EnhancerByCGLIB$$91e58a41; 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); Object var10000; switch(var1) { case 0: var10000 = this.CGLIB$CALLBACK_0; break; case 1: var10000 = this.CGLIB$CALLBACK_1; break; case 2: var10000 = this.CGLIB$CALLBACK_2; break; case 3: var10000 = this.CGLIB$CALLBACK_3; break; case 4: var10000 = this.CGLIB$CALLBACK_4; break; case 5: var10000 = this.CGLIB$CALLBACK_5; break; default: var10000 = null; } return (Callback)var10000; } public void setCallback(int var1, Callback var2) { switch(var1) { case 0: this.CGLIB$CALLBACK_0 = (NoOp)var2; break; case 1: this.CGLIB$CALLBACK_1 = (MethodInterceptor)var2; break; case 2: this.CGLIB$CALLBACK_2 = (LazyLoader)var2; break; case 3: this.CGLIB$CALLBACK_3 = (InvocationHandler)var2; break; case 4: this.CGLIB$CALLBACK_4 = (FixedValue)var2; break; case 5: this.CGLIB$CALLBACK_5 = (Dispatcher)var2; } } public Callback[] getCallbacks() { CGLIB$BIND_CALLBACKS(this); return new Callback[]{this.CGLIB$CALLBACK_0, this.CGLIB$CALLBACK_1, this.CGLIB$CALLBACK_2, this.CGLIB$CALLBACK_3, this.CGLIB$CALLBACK_4, this.CGLIB$CALLBACK_5}; } public void setCallbacks(Callback[] var1) { this.CGLIB$CALLBACK_0 = (NoOp)var1[0]; this.CGLIB$CALLBACK_1 = (MethodInterceptor)var1[1]; this.CGLIB$CALLBACK_2 = (LazyLoader)var1[2]; this.CGLIB$CALLBACK_3 = (InvocationHandler)var1[3]; this.CGLIB$CALLBACK_4 = (FixedValue)var1[4]; this.CGLIB$CALLBACK_5 = (Dispatcher)var1[5]; } static { CGLIB$STATICHOOK1(); } }
到此这篇关于Java中Cglib代理类重写逻辑详解的文章就介绍到这了,更多相关Cglib代理类重写逻辑内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!