動態代理的兩種方式以及區別
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則使用的繼承機制,具體說被代理類和代理類是繼承關係,所以代理類是可以賦值給被代理類的,如果被代理類有介面,那麼代理類也可以賦值給介面。
相關文章
- (十七)關於動態代理,你能說出動態代理的幾種方式?
- javascript兩種宣告函式方式的區別JavaScript函式
- Golang兩種執行流程以及區別Golang
- HTTP代理的兩種連線方式HTTP
- cglib動態代理和jdk動態代理的區別與應用CGLibJDK
- java執行緒實現的三種方式以及靜態代理Java執行緒
- 住宅代理的兩種型別型別
- hibernate中建立session的兩種方式方式,區別在哪裡?Session
- 動態代理jdk和cglib的區別JDKCGLib
- Javascript中兩種方式定義函式的區別JavaScript函式
- 請教兩種Singleton Pattern 實現方式的區別!
- Android 動態代理以及利用動態代理實現 ServiceHookAndroidHook
- js動態往div裡新增按鈕的兩種方式以及jQuery中$.each的用法詳解JSjQuery
- 求陣列長度的兩種方法,以及區別(strlen sizeof)陣列
- JavaScript建立閉包的兩種方式的優劣與區別分析JavaScript
- redis的php驅動兩種方式RedisPHP
- 【4】JDK和CGLIB生成動態代理類的區別JDKCGLib
- 兩種增量備份的區別!
- 三種連結方式的區別
- 設計模式總結——代理模式以及java的動態代理設計模式Java
- 擴充套件類的三種方式(繼承,裝飾模式,動態代理)套件繼承模式
- JDK 和 CGLib 實現動態代理和區別JDKCGLib
- asp.net 中兩種不同方式檔案流下載的區別?ASP.NET
- Spring AOP --JDK動態代理方式SpringJDK
- spring bean別名的兩種配置方式SpringBean
- IOS檢測晃動的兩種方式iOS
- 兩種啟動資料庫的方式資料庫
- 兩種動態建立表格的方法
- hash和history兩種模式的區別模式
- 【乾貨】JDK動態代理的實現原理以及如何手寫一個JDK動態代理JDK
- 為什麼 Go 有兩種宣告變數的方式,有什麼區別,哪種好?Go變數
- 多執行緒的建立 兩種方式以及使用建議執行緒
- java執行原理、靜態代理和動態代理區分Java
- vue-router的兩種模式的區別Vue模式
- 動態ip代理的三種使用方法
- Maven和Ant簡介以及兩者的區別Maven
- Java動態代理與靜態代理以及它能為我們做什麼Java
- Mysql兩種主要資料引擎的區別MySql