淺析Java中的動態(tài)代理
代理常見功能
日志代理
數據庫訪問的事務代理
代理模式的組成
- 抽象主題:通過接口或抽象類定義核心業(yè)務方法。
- 真實主題:實現了接口的實現類,是實施代理的具體對象。即代理最終代理的是具體的實現類類而不是接口。
- 代理:具有與代理對象相同的方法,可以控制和擴展被代理對象的功能,也是使用代理對象的根據目的。
代理對象 = 增強代碼 + 目標對象(原對象)
代理模式分類
靜態(tài)代理:代理類與被代理類一一對應,缺點是代理類太多。
動態(tài)代理:代理類是運行時通過反射技術動態(tài)生成的。有點是一類相似功能的被代理類(即需要相同擴展功能的類)只需要一個動態(tài)代理類。
動態(tài)代理實現的技術
JDK 代理:面向接口的代理,無法直接代理類,被代理的類必須實現某業(yè)務接口。
CGLIB 代理:功能更強,性能更好,可以直接代理類而不用實現接口,是通過動態(tài)創(chuàng)建被代理的子類重寫父類的被代理方法來實現統(tǒng)計附件功能的。不能代理final類或final方法。
JDK 代理的實現步驟
核心業(yè)務接口
public interface Buyer {
/**
* 賣房:核心業(yè)務方法
* @return
*/
String buy();
}
業(yè)務實現類
public class BuyerImpl implements Buyer{
public String buy() {
System.out.println("本人賣房,從不坑人...");
return "一次搞定";
}
}
動態(tài)代理類
public class BuyerInvocationHandler implements InvocationHandler {
//被代理對象
private Object target;
/**
* 設置被代理對象
* @param target
*/
public void setTarget(Object target) {
this.target = target;
}
/**
* 執(zhí)行被代理對象的業(yè)務方法的代理方法
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("熬夜?jié)M大街收集電話號碼.....");
//調用核心業(yè)務方法
Object result = method.invoke(target,args);
System.out.println("不滿意,再找我...");
return result;
}
}
代理工廠類
public class BuyerProxyFactory {
/**
* 工廠方法
* @param target 需要被代理的對象
* @param <T>
* @return 返回動態(tài)生成的代理對象
*/
public static <T> T create(Object target){
// 創(chuàng)建動態(tài)代理對象
BuyerInvocationHandler handler = new BuyerInvocationHandler();
// 設置被代理對象
handler.setTarget(target);
// 動態(tài)創(chuàng)建執(zhí)行業(yè)務方法的代理對象
return (T) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
handler);
}
}測試類
public class example {
public static void main(String[] args) {
//定義被代理對象
//定義被代理對象
Buyer buyer = new BuyerImpl();
buyer.buy(); // 直接調用業(yè)務方法,沒有代理的功能
// 使用代理工廠創(chuàng)建動態(tài)代理類對象
Buyer proxyBuyer = BuyerProxyFactory.create(buyer);
proxyBuyer.buy();
}
}
CGLIB 代理實現步驟
導入 POM
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>3.3.0</version>
</dependency>
定義業(yè)務方法
public class OrderService {
public int insert(){
System.out.println("添加訂單....");
return 0;
}
}
定義代理工廠類,與提供事務控制功能的MethodInterceptor合二為一
public class TransactionProxyFactory {
/**
* 動態(tài)創(chuàng)建被代理類的代理對象
* @param clazz 類型
* @param <T>
* @return 代理對象
*/
public static <T> T create(Class<T> clazz){
Enhancer enhancer = new Enhancer();
// 采用接口內部類的方式實現代理功能
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object target, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("開始事務。。。。");
// 核心業(yè)務,調用父類的方法
Object result = methodProxy.invokeSuper(target,objects);
System.out.println("提交或回滾事務....");
return result;
}
});
// 設置代理類的父類
enhancer.setSuperclass(clazz);
// 返回創(chuàng)建的動態(tài)代理類對象
return (T) enhancer.create();
}
}測試類
public class TransactionProxyFactoryTest {
public static void main(String[] args) {
// 使用代理創(chuàng)建業(yè)務邏輯類
OrderService orderService =
TransactionProxyFactory.create(OrderService.class);
orderService.insert();
CartService cartService = TransactionProxyFactory.create(CartService.class);
cartService.insert();
}
}
到此這篇關于淺析Java中的動態(tài)代理的文章就介紹到這了,更多相關Java動態(tài)代理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
netty服務端輔助類ServerBootstrap創(chuàng)建邏輯分析
這篇文章主要介紹了netty服務端輔助類ServerBootstrap創(chuàng)建邏輯分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-03-03
關于Spring Boot動態(tài)權限變更問題的實現方案
這篇文章主要介紹了Spring Boot動態(tài)權限變更實現的整體方案使用session作為緩存,結合AOP技術進行token認證和權限控制,本文給大家介紹的非常詳細,需要的朋友參考下吧2021-06-06
Spring使用RestTemplate模擬form提交示例
本篇文章主要介紹了Spring使用RestTemplate模擬form提交示例,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03

