jdk動態(tài)代理源碼分析過程
代理對象的生成方法是:
Proxy.newProxyInstance(...)
,進入這個方法內(nèi)部,一步一步往下走會發(fā)現(xiàn)會調(diào)用
ProxyGenerator.generateProxyClass()
,這個方法用來生成代理類的字節(jié)碼。
下面通過調(diào)用 ProxyGenerator.generateProxyClass()方法在本地生成代理類。
1.首先要有一個接口
2.生成代理類的方法如下
3.將生成的代理類導(dǎo)入到idea中查看是長這樣
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // import com.example.springboottest.config.OrderService; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; protected static class $OrderService extends Proxy implements OrderService { private static Method m1; private static Method m3; private static Method m2; private static Method m0; public $OrderService(InvocationHandler var1) throws { super(var1); } public final boolean equals(Object var1) throws { try { return (Boolean)super.h.invoke(this, m1, new Object[]{var1}); } catch (RuntimeException | Error var3) { throw var3; } catch (Throwable var4) { throw new UndeclaredThrowableException(var4); } } public final void query() throws { try { super.h.invoke(this, m3, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } public final String toString() throws { try { return (String)super.h.invoke(this, m2, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } public final int hashCode() throws { try { return (Integer)super.h.invoke(this, m0, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object")); m3 = Class.forName("com.example.springboottest.config.OrderService").getMethod("query"); m2 = Class.forName("java.lang.Object").getMethod("toString"); m0 = Class.forName("java.lang.Object").getMethod("hashCode"); } catch (NoSuchMethodException var2) { throw new NoSuchMethodError(var2.getMessage()); } catch (ClassNotFoundException var3) { throw new NoClassDefFoundError(var3.getMessage()); } } }
可以發(fā)現(xiàn)在代理類中的構(gòu)造方法中傳入了我們實現(xiàn)的InvocationHandler,在調(diào)用方法時會回調(diào)invoke方法。
還可以發(fā)現(xiàn)代理類中繼承了Proxy,由于java中是單繼承的,所以java動態(tài)代理是針對接口的。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring和SpringMVC父子容器關(guān)系初窺(小結(jié))
這篇文章主要介紹了Spring和SpringMVC父子容器關(guān)系初窺(小結(jié)),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01Springcloud Bus消息總線原理是實現(xiàn)詳解
Spring Cloud Bus 使用輕量級的消息代理來連接微服務(wù)架構(gòu)中的各個服務(wù),可以將其用于廣播狀態(tài)更改(例如配置中心配置更改)或其他管理指令,本文將對其用法進行詳細介紹2022-09-09MyBatis 執(zhí)行動態(tài) SQL語句詳解
大家對mybatis執(zhí)行任意sql語句都了解,那么MyBatis執(zhí)行動態(tài)SQL語句呢?下面腳本之家小編給大家解答下mybatis執(zhí)行動態(tài)sql語句的方法,非常不錯,感興趣的朋友參考下吧2016-08-08SpringBoot對不同Bean注解的區(qū)別和使用場景說明
這篇文章主要介紹了SpringBoot對不同Bean注解的區(qū)別和使用場景說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03