首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring AOP 前奏:JDK 動態代理原理與實戰

     編輯:Java 綜合教學

Spring AOP 前奏:JDK 動態代理原理與實戰

動態代理是 AOP 實現的核心基礎。JDK 動態代理基於接口,通過 java.lang.reflect.Proxy 與 InvocationHandler 實現方法攔截與增強。本文以性能監控為例,演示從需求分析到代碼實現的完整過程。

痛點:侵入式日志的弊端

  • 代碼分散、重複,違反開閉原則;
  • 業務邏輯與橫切關注點(日志、事務、監控)耦合;
  • 維護成本高,易引入錯誤。

動態代理解決方案

  1. 定義公共接口 MyProxy;
  2. 目標類 OldClass 實現接口;
  3. 實現 InvocationHandler,在 invoke 中織入監控邏輯;
  4. 通過 Proxy.newProxyInstance 生成代理對象;
  5. 客戶端調用代理而非原始對象。

完整代碼示例

// 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) 反射調用真實目標方法;
  • 限制:目標類必須實現接口,無接口類需使用 CGLIB(子類代理)。

Spring AOP 的進一步封裝

Spring 在此基礎上提供 ProxyFactoryBean、@EnableAspectJAutoProxy 等高級抽象,自動處理代理創建、切面織入、切點匹配等,開發者專注於切面邏輯編寫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved