動態代理是 AOP 實現的核心基礎。JDK 動態代理基於接口,通過 java.lang.reflect.Proxy 與 InvocationHandler 實現方法攔截與增強。本文以性能監控為例,演示從需求分析到代碼實現的完整過程。
MyProxy;OldClass 實現接口;InvocationHandler,在 invoke 中織入監控邏輯;Proxy.newProxyInstance 生成代理對象;// 1. 接口
public interface MyProxy {
void method1() throws InterruptedException;
void method2() throws InterruptedException;
void method3() throws InterruptedException;
}
// 2. 目標類
public class OldClass implements MyProxy {
@Override public void method1() throws InterruptedException {
System.out.println("正在處理業務邏輯1"); Thread.sleep(100); System.out.println("業務邏輯1處理完成");
}
@Override public void method2() throws InterruptedException { /* 類似 */ }
@Override public void method3() throws InterruptedException { /* 類似 */ }
}
// 3. 調用處理器
public class MyInvocationHandler<T> implements InvocationHandler {
private final T target;
public MyInvocationHandler(T target) { this.target = target; }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long start = System.currentTimeMillis();
Object result = method.invoke(target, args);
System.out.println("方法 " + method.getName() + " 調用結束,耗時 " + (System.currentTimeMillis() - start) + "ms");
return result;
}
}
// 4. 測試
public class MainTest {
public static void main(String[] args) throws Exception {
OldClass old = new OldClass();
InvocationHandler handler = new MyInvocationHandler<>(old);
MyProxy proxy = (MyProxy) Proxy.newProxyInstance(
MyProxy.class.getClassLoader(),
new Class[]{MyProxy.class},
handler
);
proxy.method1();
proxy.method2();
proxy.method3();
}
}
正在處理業務邏輯1
業務邏輯1處理完成
方法 method1 調用結束,耗時 101ms
正在處理業務邏輯2
業務邏輯2處理完成
方法 method2 調用結束,耗時 200ms
正在處理業務邏輯3
業務邏輯3處理完成
方法 method3 調用結束,耗時 301ms
Proxy.newProxyInstance 動態生成實現指定接口的匿名類;InvocationHandler.invoke;method.invoke(target, args) 反射調用真實目標方法;Spring 在此基礎上提供 ProxyFactoryBean、@EnableAspectJAutoProxy 等高級抽象,自動處理代理創建、切面織入、切點匹配等,開發者專注於切面邏輯編寫。