[學習原創] java.lang.reflect.Proxy使用


最近沒事,看了一下Spring的書籍,從它最開始的AOP1到AOP2,於是對基本的實現原理有了一種探究的想法,AOP1用的Dynamic Proxy的模式是從1.3引入,其本質就是生成代理類,包裝原有的對象,將原有對象的方法指派給包裝后生成的代理類,在方法調用前后,甚至於方法調用上做手腳,這個手腳就要具體看是什么業務邏輯。

 

Proxy的代碼很簡單,核心就是newProxyInstance,接收參數為類加載器,接口,包裝的InvokecationHandler,代碼如下:

 1          /*
 2           * Look up or generate the designated proxy class.
 3            */
 4         Class<?> cl = getProxyClass(loader, interfaces);
 5 
 6          /*
 7           * Invoke its constructor with the designated invocation handler.
 8            */
 9          try {
10             Constructor cons = cl.getConstructor(constructorParams);
11              return cons.newInstance( new Object[] { h });
12         }  catch (NoSuchMethodException e) {
13              throw  new InternalError(e.toString());
14         }  catch (IllegalAccessException e) {
15              throw  new InternalError(e.toString());
16         }  catch (InstantiationException e) {
17              throw  new InternalError(e.toString());
18         }  catch (InvocationTargetException e) {
19              throw  new InternalError(e.toString());
20         }

代碼很簡單,1、要獲取代理類;2、根據代理類的構造方法反射生成對象。

 

Sun在內部是調用了ProxyGenerator這個類來處理的,因為它有一個屬性能夠將生成的class字節碼打印到本地文件系統:

System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

在代碼中將這個屬性開關打開就可以存儲class文件,然后用類似的反編譯工具可以看出詳細的生成內容,我建議這么做,因為Proxy的API文檔說的很玄乎,如果不對照生成的class文件來看的,真的很難透徹的理解其本質含義。

 

Proxy的模式相對來說,效率還是很低的,雖然緩存了方法對象,但是性能上肯定要比普通調用少不少。

 

后續:

1、把ProxyGenerator分析后,再來補充這篇文檔

2、對比CGLIB,以及其他AOP的工具來分析

 

雖然網上有很多類似文章,但是我覺得只有自己深入的透徹的分析才能實實在在的學習到知識。

 

后記:

 

1、關於ProxyGenerator, google時候發現openjdk網上有這個源碼:http://cr.openjdk.java.net/~sherman/7084245/webrev/src/share/classes/sun/misc/ProxyGenerator.java-.html

里面的注釋寫的非常清晰,可以參考。

2、感覺JDK里面這個代碼寫的不是特別好,NetBean里面的可能進行修正了,這個效果不錯:

http://kickjava.com/src/org/netbeans/mdr/util/ImplGenerator.java.htm

3、SF上這個工程也不錯:

http://rejava.sourceforge.net/hello_en.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM