參考 http://lrd.ele.me/2017/01/09/dynamic_proxy/
jdk 代理
rem target 實例化的對象
--> Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
--> Class<?> cl = getProxyClass0(loader, intfs); // intfs 對象接口
重點 :
--> return proxyClassCache.get(loader, interfaces); // proxyClassCache 緩存
--> Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter)); // 獲取subkey [KeyFactory類型] subKeyFactory
--> Supplier<V> supplier = valuesMap.get(subKey); value 域 <ProxyClassFactory> 類型 supplier.apply() == ProxyClassFactory.apply()
--> Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
//Verify that the class loader resolves the name of this interface to the same Class object.
//Verify that the Class object actually represents an interface.
//Verify that this interface is not a duplicate.
--> interfaceClass = Class.forName(intf.getName(), false, loader); // 逐個遍歷 interfaces
--> long num = nextUniqueNumber.getAndIncrement();
--> String proxyName = proxyPkg + proxyClassNamePrefix + num; //生成名稱
--> byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces, accessFlags); // 生成classbyte [核心]
--> return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length); //定義類
--> factory = new Factory(key, parameter, subKey, valuesMap);// valueFactory 即 valuesMap 中 value 的封裝
--> final Constructor<?> cons = cl.getConstructor(constructorParams);
--> final InvocationHandler ih = h;
--> return cons.newInstance(new Object[]{h});
生成$Proxy0 class 反編譯
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m3 = Class.forName("BookFacade").getMethod("addBook");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
生成的方法
public final void addBook() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
jdk proxy的調(diào)用是一個反射調(diào)用的過程
cglib 動態(tài)代理的實現(xiàn)分析
代理類繼承自org.springframework.cglib.proxy.MethodInterceptor 實現(xiàn)intercept方法
關(guān)鍵代碼 ::
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass()); // 將接口直接設(shè)置成BookFacadeProxyCglib 實現(xiàn)類
// 回調(diào)方法
// enhancer.setCallbackType(this.getClass());
enhancer.setCallback(this); //設(shè)置回調(diào)
// 創(chuàng)建代理對象
return enhancer.create();
--> return this.createHelper();
--> this.setNamePrefix(this.superclass.getName());設(shè)置NamePrefix
--> return super.create(KEY_FACTORY.newInstance(this.superclass != null ? this.superclass.getName() : null, ReflectUtils.getNames(this.interfaces), this.filter, this.callbackTypes, this.useFactory, this.interceptDuringConstruction, this.serialVersionUID));
// 代理產(chǎn)生的幾個類
fastclass --> public class BookFacadeImpl$$EnhancerByCGLIB$$677aba98$$FastClassByCGLIB$$dcb5b9cc extends FastClass
class --> public class BookFacadeImpl$$EnhancerByCGLIB$$677aba98 extends BookFacadeImpl implements Factory
keyFactory --> public class Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$4ce19e8f extends KeyFactory implements EnhancerKey
methodwrapperkey --> public class MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$552be97a extends KeyFactory implements MethodWrapperKey
整個aop執(zhí)行過程
[ BookFacadeImpl$$EnhancerByCGLIB$$677aba98 ] addbook
--> [ MethodIntercepter.intercept ]
< before method exe >
--> [ BookFacadeImpl$$EnhancerByCGLIB$$677aba98$$FastClassByCGLIB$$dcb5b9cc.invoke ]
--> [ BookFacadeImpl$$EnhancerByCGLIB$$677aba98.CGLIB$addBook$0 >>>> (final 方法) ]
--> [ super[BookFacadeImpl].addBook ]
< after method exe >
--> [ MethodIntercepter.intercept ]
調(diào)用路徑
//使用的是這個對象
--> BookFacadeImpl$$EnhancerByCGLIB$$677aba98
| private boolean CGLIB$BOUND;
| private static final ThreadLocal CGLIB$THREAD_CALLBACKS; //threadlocal 中存放callback
| private static final Callback[] CGLIB$STATIC_CALLBACKS; // static callback
| private MethodInterceptor CGLIB$CALLBACK_0; // 用戶自己實現(xiàn)的MethodInterceptor
| private static final Method CGLIB$addBook$0$Method; // 父類中的callback 方法
| private static final MethodProxy CGLIB$addBook$0$Proxy; // 方法代理 MethodProxy 類
| private static final Object[] CGLIB$emptyArgs; // 方法參數(shù)
| 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 var0 = Class.forName("BookFacadeImpl$$EnhancerByCGLIB$$677aba98"); //當(dāng)前類的實例
| Class var1;
| Method[] var10000 = ReflectUtils.findMethods(new String[]{"finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
| CGLIB$finalize$1$Method = var10000[0];
| CGLIB$finalize$1$Proxy = MethodProxy.create(var1, var0, "()V", "finalize", "CGLIB$finalize$1");
| CGLIB$equals$2$Method = var10000[1];
| CGLIB$equals$2$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$2");
| CGLIB$toString$3$Method = var10000[2];
| CGLIB$toString$3$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$3");
| CGLIB$hashCode$4$Method = var10000[3];
| CGLIB$hashCode$4$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$4");
| CGLIB$clone$5$Method = var10000[4];
| CGLIB$clone$5$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$5");
// var1 賦值
| CGLIB$addBook$0$Method = ReflectUtils.findMethods(new String[]{"addBook", "()V"}, (var1 = Class.forName("BookFacadeImpl")).getDeclaredMethods())[0];
| CGLIB$addBook$0$Proxy = MethodProxy.create(var1, var0, "()V", "addBook", "CGLIB$addBook$0");
| }
--> addBook()
-->
-->| public final void addBook() {
-->| MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;//獲取當(dāng)前類中的methodintercepter
-->| if (this.CGLIB$CALLBACK_0 == null) {
-->| CGLIB$BIND_CALLBACKS(this); //如果為空
-->| var10000 = this.CGLIB$CALLBACK_0;
-->| }
-->|
-->| if (var10000 != null) {
// 執(zhí)行MethodInterceptor 類中的方法 <實現(xiàn)了MethodInterceptor的類> -->
-->| var10000.intercept(this, CGLIB$addBook$0$Method, CGLIB$emptyArgs, CGLIB$addBook$0$Proxy);
-->| } else {
-->| super.addBook();
-->| }
-->| }
-->| private static final void CGLIB$BIND_CALLBACKS(Object var0) {
-->| BookFacadeImpl$$EnhancerByCGLIB$$677aba98 var1 = (BookFacadeImpl$$EnhancerByCGLIB$$677aba98)var0;
-->| if (!var1.CGLIB$BOUND) {
-->| var1.CGLIB$BOUND = true;
-->| Object var10000 = CGLIB$THREAD_CALLBACKS.get();
-->| if (var10000 == null) {
-->| var10000 = CGLIB$STATIC_CALLBACKS;
-->| if (CGLIB$STATIC_CALLBACKS == null) {
-->| return;
-->| }
-->| }
-->|
-->| var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
-->| }
-->|
-->| }
實現(xiàn)了 MethodInterceptor的類
-->|>|public class BookFacadeProxyCglib implements MethodInterceptor {
-->|>| private Object target;
-->|>|
-->|>| public Object getInstance(Object target) {
-->|>| this.target = target;
-->|>| Enhancer enhancer = new Enhancer();
-->|>| enhancer.setSuperclass(this.target.getClass());
-->|>| // 回調(diào)方法
-->|>| // enhancer.setCallbackType(this.getClass());
-->|>| enhancer.setCallback(this);
-->|>| // 創(chuàng)建代理對象
-->|>| return enhancer.create();
-->|>| }
-->|>|
-->|>| @Override
-->|>| public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
-->|>| System.out.println("before run!");
// 執(zhí)行MethodProxy的invokeSuper
-->|>| proxy.invokeSuper(obj, args);
-->|>| System.out.println("after run!");
-->|>| return null;
-->|>| }
-->|>|}
MethodProxy的invokeSuper 方法
-->| public Object invokeSuper(Object obj, Object[] args) throws Throwable {
-->| try {
-->| this.init();
------> | private void init() {
------> | if (this.fastClassInfo == null) {
------> | Object var1 = this.initLock;
------> | synchronized(this.initLock) {
------> | if (this.fastClassInfo == null) {
------> | MethodProxy.CreateInfo ci = this.createInfo;
----------------------- 對應(yīng) --> CGLIB$addBook$0$Proxy = MethodProxy.create(var1, var0, "()V", "addBook", "CGLIB$addBook$0");
MethodProxy 中的變量賦值
[ c1 = var1 = BookFacadeImpl ]
[ c2 = var0 = BookFacadeImpl$$EnhancerByCGLIB$$677aba98 ]
[ name1 = addBook = new Signature(name1, desc); ]
[ name2 = CGLIB$addBook$0 = new Signature(name2, desc); ]
--> | 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 MethodProxy.CreateInfo(c1, c2);
--> | return proxy;
--> | }
-----------------------
------> | MethodProxy.FastClassInfo fci = new MethodProxy.FastClassInfo(); //實例化FastClassInfo
------> | fci.f1 = helper(ci, ci.c1);
----------------------------------------------------------------------------------------------------------------------
---->| private static FastClass helper(MethodProxy.CreateInfo ci, Class type) {
---->| Generator g = new Generator();
---->| g.setType(type);
---->| g.setClassLoader(ci.c2.getClassLoader());
---->| g.setNamingPolicy(ci.namingPolicy);
---->| g.setStrategy(ci.strategy);
---->| g.setAttemptLoad(ci.attemptLoad);
---->| return g.create();
>| org.springframework.cglib.core.AbstractClassGenerator#create //最終調(diào)用AbstractClassGenerator的create方法
---->| }
----------------------------------------------------------------------------------------------------------------------
------> | fci.f2 = helper(ci, ci.c2);
------> | fci.i1 = fci.f1.getIndex(this.sig1);
------> | fci.i2 = fci.f2.getIndex(this.sig2);
------> | this.fastClassInfo = fci;
------> | this.createInfo = null;
------> | }
------> | }
------> | }
------> | }
-->| MethodProxy.FastClassInfo fci = this.fastClassInfo;
-->| return fci.f2.invoke(fci.i2, obj, args);
-->| } catch (InvocationTargetException var4) {
-->| throw var4.getTargetException();
-->| }
-->| }