Java動態代理是一種設計模式,允許在運行時創建代理對象。這種代理對象可以用來代理目標對象的方法調用,從而在不修改原始代碼的情況下增強功能。動態代理通常用於AOP(面向切面編程),比如日誌記錄、許可權控制和事務管理。
動態代理的基本原理
Java動態代理主要依賴於java.lang.reflect包中的Proxy類和InvocationHandler介面。Proxy類用於創建代理對象,而InvocationHandler介面用於定義代理對象的行為。
當代理對象的方法被調用時,實際會調用InvocationHandler介面的invoke方法。這個方法接收三個參數:代理對象、被調用的方法對象,以及方法參數。通過invoke方法,我們可以自定義方法調用的處理邏輯。
動態代理的實現步驟
定義介面:首先定義一個介面,該介面聲明了目標對象的方法。
public interface Service {
void performTask();
}
實現介面:創建一個目標類,實現上述介面。
public class ServiceImpl implements Service {
@Override
public void performTask() {
System.out.println("執行任務");
}
}
創建InvocationHandler:實現InvocationHandler介面,重寫invoke方法。
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;
public class ServiceInvocationHandler implements InvocationHandler {
private final Object target;
public ServiceInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("方法調用前");
Object result = method.invoke(target, args);
System.out.println("方法調用後");
return result;
}
}
創建代理對象:使用Proxy類的靜態方法newProxyInstance來創建代理對象。
文章轉載自:https://www.okeyproxy.com/proxy
import java.lang.reflect.Proxy;
public class ProxyDemo {
public static void main(String[]
public static void main(String[] args) {
// 創建目標對象
Service target = new ServiceImpl();
// 創建InvocationHandler
ServiceInvocationHandler handler = new ServiceInvocationHandler(target);
// 創建代理對象
Service proxy = (Service) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
handler
);
// 調用代理對象的方法
proxy.performTask();
}
}
在這個例子中,Proxy.newProxyInstance方法創建了一個代理對象。這個代理對象實現了Service介面,並將所有方法調用委託給ServiceInvocationHandler的invoke方法。
動態代理的應用場景
- 日誌記錄:在方法調用前後自動記錄日誌。
- 許可權控制:根據用戶許可權決定是否允許方法調用。
- 事務管理:在方法調用前後自動管理事務。
- 遠程方法調用:將本地調用轉發到遠程服務。
動態代理與靜態代理的區別
- 實現方式:靜態代理需要為每個介面創建代理類,而動態代理在運行時生成代理類。
- 靈活性:動態代理更加靈活,因為它不依賴於具體的代理類實現。
- 性能:動態代理由於是在運行時生成,可能稍微影響性能,但在大多數應用場景中,這種影響是可以忽略不計的。