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

Java 動態代理機制深度解析:InvocationHandler 與 Proxy 實現 AOP 核心原理

     編輯:Java 綜合教學

Java 動態代理機制深度解析:InvocationHandler 與 Proxy 實現 AOP 核心原理

Spring AOP 的底層基石是 JDK 動態代理。本文通過接口定義、目標對象、代理類、客戶端調用的完整鏈路,圖解 InvocationHandler 與 Proxy 協作機制,助你徹底理解動態代理原理。

核心兩大組件

組件類型核心職責
InvocationHandler接口定義 invoke(proxy, method, args),攔截代理方法調用,決定如何轉發/增強
Proxy類提供 newProxyInstance(loader, interfaces, handler) 動態生成代理類實例

完整代碼演示

1. 業務接口

public interface Subject {
    void rent();
    void hello(String str);
}

2. 真實對象

public class RealSubject implements Subject {
    @Override public void rent() { System.out.println("I want to rent my house"); }
    @Override public void hello(String str) { System.out.println("hello: " + str); }
}

3. 動態代理類(實現 InvocationHandler)

public class DynamicProxy implements InvocationHandler {
    private final Object subject; // 被代理目標
    public DynamicProxy(Object subject) { this.subject = subject; }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before rent house");
        System.out.println("Method: " + method);
        Object result = method.invoke(subject, args); // 反射調用目標方法
        System.out.println("after rent house");
        return result;
    }
}

4. 客戶端創建代理並調用

public class Client {
    public static void main(String[] args) {
        Subject real = new RealSubject();
        InvocationHandler handler = new DynamicProxy(real);

        // 三要素:類加載器、實現接口數組、處理器
        Subject proxy = (Subject) Proxy.newProxyInstance(
            handler.getClass().getClassLoader(),
            real.getClass().getInterfaces(),
            handler
        );

        System.out.println(proxy.getClass().getName()); // $Proxy0
        proxy.rent();
        proxy.hello("world");
    }
}

輸出與關鍵點解讀

$Proxy0
before rent house
Method: public abstract void com.xiaoluo.dynamicproxy.Subject.rent()
I want to rent my house
after rent house
before rent house
Method: public abstract void com.xiaoluo.dynamicproxy.Subject.hello(java.lang.String)
hello: world
after rent house
  1. $Proxy0:JVM 運行時動態生成的類名格式,實現了 Subject 接口,繼承 Proxy,非 DynamicProxy 類型。
  2. 強轉為 Subject 合法:因 newProxyInstance 第二參數傳入 real.getClass().getInterfaces(),代理類實現了這些接口,滿足多態。
  3. 調用流向:proxy.rent() → 生成的代理類方法 → handler.invoke() → method.invoke(subject, args) → 真實對象。
  4. 增強點:invoke 中可在目標調用前後插入邏輯(事務、日誌、權限),這正是 AOP 的本質。

JDK 動態代理 vs CGLIB

Spring 默認:有接口用 JDK,無接口用 CGLIB。可強制 proxy-target-class=true 全用 CGLIB。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
維度JDK 動態代理CGLIB
前提目標實現至少一個接口無需接口,繼承目標類
機制生成實現接口的代理類生成目標類子類,重寫方法
final 方法不可代理不可代理
性能調用稍快(JDK 8+ 優化)創建快,調用稍慢