動態代理的兩種方式以及區別
JDK動態代理:利用反射機制生成一個實現代理介面的匿名類,在呼叫具體方法前呼叫InvokeHandler來處理。
CGlib動態代理:利用ASM(開源的Java位元組碼編輯庫,操作位元組碼)開源包,將代理物件類的class檔案載入進來,通過修改其位元組碼生成子類來處理。
區別:JDK代理只能對實現介面的類生成代理;CGlib是針對類實現代理,對指定的類生成一個子類,並覆蓋其中的方法,這種通過繼承類的實現方式,不能代理final修飾的類。
強制使用CGlib
<!-- proxy-target-class="false"預設使用JDK動態代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<aop-config proxy-target-class="true">
<!-- 切面詳細配置 -->
</aop-config>
具體程式碼示例:
/**
* 目標介面類
*/
public interface UserManager {
public void addUser(String id, String password);
public void delUser(String id);
}
/**
* 介面實現類
*/
public class UserManagerImpl implements UserManager {
@Override
public void addUser(String id, String password) {
System.out.println("呼叫了UserManagerImpl.addUser()方法!");
}
@Override
public void delUser(String id) {
System.out.println("呼叫了UserManagerImpl.delUser()方法!");
}
}
/**
* JDK動態代理類
*/
public class JDKProxy implements InvocationHandler {
// 需要代理的目標物件
private Object targetObject;
public Object newProxy(Object targetObject) {
// 將目標物件傳入進行代理
this.targetObject = targetObject;
// 返回代理物件
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
}
// invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 進行邏輯處理的函式
checkPopedom();
Object ret = null;
// 呼叫invoke方法
ret = method.invoke(targetObject, args);
return ret;
}
private void checkPopedom() {
// 模擬檢查許可權
System.out.println("檢查許可權:checkPopedom()!");
}
}
/**
* CGlib動態代理類
*/
public class CGLibProxy implements MethodInterceptor {
// CGlib需要代理的目標物件
private Object targetObject;
public Object createProxyObject(Object obj) {
this.targetObject = obj;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(obj.getClass());
enhancer.setCallback(this);
Object proxyObj = enhancer.create();
return proxyObj;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object obj = null;
// 過濾方法
if ("addUser".equals(method.getName())) {
// 檢查許可權
checkPopedom();
}
obj = method.invoke(targetObject, args);
return obj;
}
private void checkPopedom() {
System.out.println("檢查許可權:checkPopedom()!");
}
}
/**
* 測試類
*/
public class ProxyTest {
public static void main(String[] args) {
UserManager userManager = (UserManager)new CGLibProxy().createProxyObject(new UserManagerImpl());
System.out.println("CGLibProxy:");
userManager.addUser("tom", "root");
System.out.println("JDKProxy:");
JDKProxy jdkProxy = new JDKProxy();
UserManager userManagerJDK = (UserManager)jdkProxy.newProxy(new UserManagerImpl());
userManagerJDK.addUser("tom", "root");
}
}
// 執行結果
CGLibProxy:
檢查許可權checkPopedom()!
呼叫了UserManagerImpl.addUser()方法!
JDKProxy:
檢查許可權checkPopedom()!
掉用了UserManagerImpl.addUser()方法!
總結:1.JDK代理使用的是反射機制實現aop的動態代理,CGLIB代理使用位元組碼處理框架asm,通過修改位元組碼生成子類。所以jdk動態代理的方式建立代理物件效率較高,執行效率較低,cglib建立效率較低,執行效率高;2.JDK動態代理機制是委託機制,具體說動態實現介面類,在動態生成的實現類裡面委託hanlder去呼叫原始實現類方法,CGLIB則使用的繼承機制,具體說被代理類和代理類是繼承關係,所以代理類是可以賦值給被代理類的,如果被代理類有介面,那麼代理類也可以賦值給介面。
相關文章
- (十七)關於動態代理,你能說出動態代理的幾種方式?
- Golang兩種執行流程以及區別Golang
- cglib動態代理和jdk動態代理的區別與應用CGLibJDK
- HTTP代理的兩種連線方式HTTP
- 動態代理jdk和cglib的區別JDKCGLib
- java執行緒實現的三種方式以及靜態代理Java執行緒
- 住宅代理的兩種型別型別
- js動態往div裡新增按鈕的兩種方式以及jQuery中$.each的用法詳解JSjQuery
- 求陣列長度的兩種方法,以及區別(strlen sizeof)陣列
- JavaScript建立閉包的兩種方式的優劣與區別分析JavaScript
- JDK 和 CGLib 實現動態代理和區別JDKCGLib
- Spring AOP --JDK動態代理方式SpringJDK
- asp.net 中兩種不同方式檔案流下載的區別?ASP.NET
- 設計模式總結——代理模式以及java的動態代理設計模式Java
- 兩種動態建立表格的方法
- 死磕Spring之AOP篇 - 初識JDK、CGLIB兩種動態代理SpringJDKCGLib
- 為什麼 Go 有兩種宣告變數的方式,有什麼區別,哪種好?Go變數
- 多執行緒的建立 兩種方式以及使用建議執行緒
- 【乾貨】JDK動態代理的實現原理以及如何手寫一個JDK動態代理JDK
- java執行原理、靜態代理和動態代理區分Java
- Mysql兩種主要資料引擎的區別MySql
- 建立連結串列兩種方法的區別
- 動態ip代理的三種使用方法
- POSTMAN HTTP請求的四種方式區別PostmanHTTP
- Java動態代理與靜態代理以及它能為我們做什麼Java
- Java代理設計模式(Proxy)的四種具體實現:靜態代理和動態代理Java設計模式
- 靜態IP與動態IP有什麼區別?海外代理IP詳解
- ChatTTS的兩種使用方式TTS
- Java代理(jdk靜態代理、動態代理和cglib動態代理)JavaJDKCGLib
- 偽靜態、靜態和動態的區別
- Java 動態代理原理圖解 (附:2種實現方式詳細對比)Java圖解
- tp5 db函式的兩種區別函式
- 定義函式的兩種形式及區別函式
- Jmh測試JDK,CGLIB,JAVASSIST動態代理方式的效能JDKCGLibJava
- 靜態SDRAM和動態SDRAM的區別
- 設計模式學習筆記(七)代理模式以及動態代理的實現設計模式筆記
- 多執行緒的三種實現方式及靜態代理模式執行緒模式
- Jdk代理和CGLIB代理的區別JDKCGLib