借鑑:java
https://blog.csdn.net/yangaiyu/article/details/73827043session
若本身實現代碼加強,則須要爲每一個目標對象單獨編寫一個代理Class對象而後用類加載器加載,實例化,再調用,這樣每一個目標對象都得單獨地編寫代理Class對象以達到目的(即靜態代理)。數據結構
爲了減小代理類地編寫,咱們類的消息通常都由Class對象在JVM方法區中被加載(反射和new都是),若想不編寫代理class還要有目標類的信息,天然而然地能夠想到接口,若能對接口進行動態代理,則可將實現該接口並調用該接口中的方法(可能不止實現一個接口)的目標類歸爲以類進行代碼編寫(這就是爲何要使用動態代理的緣由),可是,接口並不能實例化jvm
但java.lang.reflect.Proxy類有個getProxyLoader(ClassLoader,interfaces)方法,只要你給他傳入類加載器和一組接口,它就能給你返回代理Class對象。(意味着它變成了一個對象,能夠帶有構造器進行實例化)函數
InvocationHandler handler = new DynamicProxy(realSubject); Object invoke(Object proxy, Method method, Object[] args) throws Throwable proxy: 指代咱們所代理的那個真實對象 method: 指代的是咱們所要調用真實對象的某個方法的Method對象 args: 指代的是調用真實對象某個方法時接受的參數
可能會覺得返回的這個代理對象會是Calculator類型的對象,或者是InvocationHandler的對象,結果卻不是,首先咱們解釋一下爲何咱們這裏能夠將其轉化爲Subject類型的對象?緣由就是在getPorxyClass這個方法的第二個參數上,咱們給這個代理對象提供了一組什麼接口,那麼我這個代理對象就會實現了這組接口,這個時候咱們固然能夠將這個代理對象強制類型轉化爲這組接口中的任意一個,由於這裏的接口是Subject類型,因此就能夠將其轉化爲Subject類型了。.net
同時咱們必定要記住,以上獲取代理Class、獲得有參構造函數、實例化後建立的代理對象是在jvm運行時動態生成的一個對象,它並非咱們的InvocationHandler類型,也不是咱們定義的那組接口的類型,而是在運行是動態生成的一個對象,而且命名方式都是這樣的形式,以$開頭,proxy爲中,最後一個數字表示對象的標號。設計
* public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException loader:一個ClassLoader對象,定義了由哪一個ClassLoader對象來對生成的代理對象進行加載 interfaces:一個Interface對象的數組,表示的是我將要給我須要代理的對象提供一組什麼接口,若是我提供了一組接口給它,那麼這個代理對象就宣稱實現了該接口(多態),這樣我就能調用這組接口中的方法了 h:一個InvocationHandler對象,表示的是當我這個動態代理對象在調用方法的時候,會關聯到哪個InvocationHandler對象上