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

JDK 動態代理核心原理與實戰:Proxy.newProxyInstance 深度解析

     編輯:Java 相關知識

JDK 動態代理基於介面,通過 java.lang.reflect.Proxy 在運行時生成代理類,核心三要素:

  • 介面:IHello(代理與被代理共同實現)
  • 目標物件:Hello 實例
  • InvocationHandler:攔截邏輯(前置/後置/異常處理)

核心 API

public static Object newProxyInstance(
    ClassLoader loader,          // 類加載器
    Class[] interfaces,       // 實現的介面列表
    InvocationHandler h          // 攔截處理器
) throws IllegalArgumentException

完整實戰代碼

public interface IHello { void hello(); }

public class Hello implements IHello {
    public void hello() { System.out.println("我是 Hello"); }
}

public class HelloTest {
    @Test public void testProxy() {
        IHello target = new Hello();
        IHello proxy = (IHello) Proxy.newProxyInstance(
            Thread.currentThread().getContextClassLoader(),
            new Class[] { IHello.class },
            new InvocationHandler() {
                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.hello(); // 輸出:開始 → 我是 Hello → 結束
    }
}

關鍵注意點

  • 只能代理介面,無法代理具體類(需 CGLIB/ByteBuddy)
  • invoke 中調用 proxy.xxx() 會無限遞歸,必須調用 target.xxx() 或 method.invoke(target, args)
  • 代理類繼承 Proxy 實現目標介面,toString()/equals()/hashCode() 會被攔截
  • 生成的代理類名格式:com.sun.proxy.$Proxy0

應用場景

  • Spring AOP(事務、日誌、權限)
  • RPC 框架客戶端存根
  • 測試 Mock、攔截器鏈
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved