標籤:ssl ima loader 部分 動態建立 作用 基於 技術 面向切面
做開發的都知道,程式設計語言可以從運行時還是編譯時間檢查分為動態類型和靜態類型。對於Java來說,通常認為它是靜態強型別語言,但是因為Java提供反射的機制,也具備了部分動態類型語言的能力。這一節,我們就講一講Java的動態代理。
動態代理是一種用於運行時動態構建代理,動態處理代理方法調用的機制。它首先是一種機制。在設計模式中有一種模式叫做代理模式(Proxy Pattern),和動態代理類似,其中代理可以看作是對調用目標的一個封裝,通過代理完成對目標對象的調用。這其實也是一種解耦。
實現動態代理的機制有很多,比如JDK自身提供的動態代理JDK Proxy(利用Java語言的反射機制),其他方式有ASM,CGLIB<基於ASM>,Javassit等。動態代理機制主要應用有面向切面AOP、攔截器、RPC調用、日誌、事務等等。
我們先來探究JDK Proxy機制<基於反射>----通過介面。新版本也開始結合ASM機制。它涉及到最重要的類和介面就是Proxy和InvocationHandler。先熟悉他們一下。
Proxy這個類的作用就是用來動態建立一個代理對象的類,它最常用到的方法是newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
InvocationHandler介面只有一個方法,每個動態代理類都必須實現這個介面。
有了初印象之後,我們再來看看一個簡單的JDK Proxy例子。
CGLIB產生動態代理的機制<基於ASM>---通過類繼承:
通過產生類的子類作為代理對象,它可以在運行期擴充Java類與實現Java介面。
CGLIB建立某個類A的動態代理類模式是:
1. 尋找A上的所有非final 的public類型的方法定義;
2. 將這些方法的定義轉換成位元組碼;
3. 將組成的位元組碼轉換成相應的代理的class對象;
4. 實現 MethodInterceptor介面,用來處理 對代理類上所有方法的請求(這個介面和JDK動態代理InvocationHandler的功能和角色是一樣的)
順便說一下Spring AOP使用不同的技術在運行時建立代理:JDK Proxy和CGLIB。
它的機制是,如果目標類實現了一個或多個介面,那麼spring將建立一個實現了每個介面的JDK動態代理。如果目標類沒有實現介面,Spring將使用CGLIB動態建立一個新類,它是目標的子類("extends")。這導致一個重要的區別:JDK Proxy無法轉為原始的目標類,因為它只是一個動態代理,恰好實現了與目標相同的介面。而CGLIB可以像目標類本身一樣。
JDK Proxy的優勢:
最小化依賴關係;
平滑進行JDK版本升級,而位元組碼類庫通常需要更新以保證新版本的java使用;
代碼實現簡單。
基於CGLIB架構的優勢:
有的時候調用目標可能不便實現額外介面,從而在運行期擴充Java類與實現Java介面;從某種角度看,限定調用者實現介面是有些侵入性的實踐,類似 cglib 動態代理就沒有這種限制;
只操作我們關心的類,而不必管其他相關類;
高效能。
歡迎關注本人公眾號
Java 動態代理的原理