Java動態(tài)代理的示例詳解
定義
動態(tài)代理指的是,代理類和目標類的關系在程序運行的時候確定的,客戶通過代理類來調用目標對象的方法,是在程序運行時根據需要動態(tài)的創(chuàng)建目標類的代理對象。
分類
jdk動態(tài)代理
cglib動態(tài)代理
案例
需求
蘋果公司通過蘋果代理商來賣手機
方案一:jdk動態(tài)代理
定義抽象接口
/**
* 售賣手機的接口(代理模式——抽象角色)
* @author:liyajie
* @createTime:2022/2/22 14:42
* @version:1.0
*/
public interface IPhone {
/**
* 出售手機
* @author: liyajie
* @date: 2022/2/22 14:44
* @param
* @return void
* @exception:
* @update:
* @updatePerson:
**/
void sellPhone();
}定義目標類實現(xiàn)接口,重寫接口方法
/**
* 蘋果公司(代理模式——目標角色)
* @author:liyajie
* @createTime:2022/2/22 14:46
* @version:1.0
*/
public class TargetPhone implements IPhone {
@Override
public void sellPhone() {
System.out.println("蘋果公司正在出售手機");
}
}定義代理類
/**
* 代理商(代理模式——代理角色)
* @author:liyajie
* @createTime:2022/2/22 14:50
* @version:1.0
*/
public class ProxyPhone {
private Object target;
public ProxyPhone(Object target){
this.target = target;
}
public Object getProxyInstance() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK動態(tài)代理開始之前,添加業(yè)務邏輯XXX");
//使用反射機制來調用目標對象的方法:解決了問題二
Object invoke = method.invoke(target, args);
System.out.println("JDK動態(tài)代理結束之后,添加業(yè)務邏輯XXX");
return invoke;
}
});
}
}定義測試類
/**
* 測試類
* @author:liyajie
* @createTime:2022/2/23 15:15
* @version:1.0
*/
public class Test {
public static void main(String[] args) {
// 創(chuàng)建目標類
TargetPhone targetPhone = new TargetPhone();
// 創(chuàng)建代理類
IPhone iPhone = (IPhone) new ProxyPhone(targetPhone).getProxyInstance();
System.out.println(iPhone.getClass());
// 通過代理類調用目標方法
iPhone.sellPhone();
}
}查看測試結果

方案二:cglib動態(tài)代理
定義目標類
/**
* 蘋果公司(代理模式——目標角色)
* @author:liyajie
* @createTime:2022/2/22 14:46
* @version:1.0
*/
public class TargetPhone {
public void sellPhone() {
System.out.println("蘋果公司正在出售手機");
}
}定義代理工廠,用來獲取代理類
/**
* 代理工廠
* @author:liyajie
* @createTime:2022/2/23 15:32
* @version:1.0
*/
public class ProxyFactory implements MethodInterceptor {
private Object target;
public ProxyFactory(Object target){
this.target = target;
}
public Object getProxyInstance(){
// 創(chuàng)建一個工具類
Enhancer enhancer = new Enhancer();
// 設置父類
enhancer.setSuperclass(target.getClass());
// 設置回調函數
enhancer.setCallback(this);
// 創(chuàng)建子類對象,即代理對象
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("cglib動態(tài)代理開始之前,添加業(yè)務邏輯xxxx");
Object invoke = method.invoke(target, objects);
System.out.println("cglib動態(tài)代理之后,添加業(yè)務邏輯");
return invoke;
}
}定義測試類
/**
* 測試類
* @author:liyajie
* @createTime:2022/2/23 15:44
* @version:1.0
*/
public class Test {
public static void main(String[] args) {
// 創(chuàng)建目標對象
TargetPhone targetPhone = new TargetPhone();
// 獲取代理對象
TargetPhone proxyInstance = (TargetPhone)new ProxyFactory(targetPhone).getProxyInstance();
// 通過代理對象調用具體的方法
proxyInstance.sellPhone();
}
}查看測試結果

分析
首先可以看到不管是jdk動態(tài)代理,還是cglib動態(tài)代理,實現(xiàn)的效果和靜態(tài)代理是一模一樣的,都實現(xiàn)了功能的擴展。但是兩種動態(tài)代理還是有些不同的,其中jdk動態(tài)代理需要目標對象實現(xiàn)接口,但是cglib動態(tài)代理不需要,因為他是在內存中構建一個子類對象,從而實現(xiàn)對目標對象的功能擴展。
總結
通過案例,我們了解了代理模式的幾種實現(xiàn)方式,下面我們總結下該模式:
優(yōu)勢:
- 代理模式在客戶端和目標對象之間起到了一個中介和保護的作用
- 代理對象可以對目標對象進行功能的擴展和業(yè)務的擴展,增強目標對象
- 代理模式可以將客戶端和目標對象分離,在一定程度上降低了系統(tǒng)的耦合度
劣勢:
- 請求需要經過代理對象,會導致處理速度變慢
- 因為會有大量的代理對象產生,會增加系統(tǒng)的復雜度
到此這篇關于Java動態(tài)代理的示例詳解的文章就介紹到這了,更多相關Java 動態(tài)代理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringMVC中RequestContextHolder獲取請求信息的方法
這篇文章主要介紹了SpringMVC中RequestContextHolder獲取請求信息的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-04-04
Java實戰(zhàn)之醫(yī)院管理系統(tǒng)的實現(xiàn)
這篇文章主要介紹了如何利用Java實現(xiàn)醫(yī)院管理系統(tǒng),文中用到的技術有:SpringBoot、Layui、Freemaker等,感興趣的同學可以了解一下2022-04-04
MyBatis?Plus如何實現(xiàn)獲取自動生成主鍵值
這篇文章主要介紹了MyBatis?Plus如何實現(xiàn)獲取自動生成主鍵值問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09
java+jsp+struts2實現(xiàn)發(fā)送郵件功能
這篇文章主要為大家詳細介紹了java+jsp+struts2實現(xiàn)發(fā)送郵件功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-03-03
Java工具之ja-netfilter?2022.1?配置教程
這篇文章主要介紹了Java工具之ja-netfilter?2022.1?配置教程,本防火墻基于javaagent,所以目前只有基于java的程序能夠使用,需要的朋友可以參考下2022-04-04

