最近沒事,看了一下Spring的書籍,從它最開始的AOP1到AOP2,於是對基本的實現原理有了一種探究的想法,AOP1用的Dynamic Proxy的模式是從1.3引入,其本質就是生成代理類,包裝原有的對象,將原有對象的方法指派給包裝后生成的代理類,在方法調用前后,甚至於方法調用上做手腳,這個手腳就要具體看是什么業務邏輯。
Proxy的代碼很簡單,核心就是newProxyInstance,接收參數為類加載器,接口,包裝的InvokecationHandler,代碼如下:
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上這個工程也不錯: