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

Java 靜態代理模式實戰:基於介面的攔截器實作

     編輯:Java 相關知識

從零手寫靜態代理:理解 AOP 核心機制

靜態代理是 AOP(面向切面編程)的基石。本範例通過一組完整的程式碼——Subject 介面、RealSubject 真實物件、MyInvocationHandler 攔截器、Proxy 動態產生代理類——展示如何在不修改原有業務邏輯的前提下,織入「方法前增強」等橫切關注點。

核心類別職責

類別角色說明
Subject介面契約定義 say()、getAllList() 業務方法
RealSubject真實實作包含業務邏輯,並重寫 equals/hashCode 演示物件比較
MyInvocationHandler攔截器實作 InvocationHandler,invoke() 中執行前置邏輯(印出「方法之前!」)再反射調用目標方法
MainTest啟動測試建立代理物件,驗證攔截生效;另附 Map 迭代、String/Integer 比較等基礎測試

關鍵程式碼解析

// 動態產生代理實例
public Object bind(Object obj) {
    this.obj = obj;
    return Proxy.newProxyInstance(
        obj.getClass().getClassLoader(),
        obj.getClass().getInterfaces(),
        this
    );
}

// 統一攔截入口
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Object result = method.invoke(this.obj, args); // 執行原方法
    System.out.println("方法之前!");             // 切面邏輯(實際常放在前置/後置/異常處理)
    return result;
}

進階延伸方向

  • CGLIB 代理:針對無介面的類,透過繼承重寫方法實現代理。
  • Spring AOP:@Aspect + @Before/@After 宣告式切面,底層即封裝了 JDK 動態代理與 CGLIB。
  • 完整切面定義:引入 MethodInterceptor、Pointcut、Advisor 概念,實現精準的切入點匹配。

常見誤區提醒

  1. 代理物件只能強轉為介面類型(Subject),不可轉為實作類(RealSubject)。
  2. equals/hashCode 若未正確重寫,集合去重、Map 鍵值查找會出現異常行為(範例中 RealSubject 的 equals 邏輯有缺陷,僅作演示)。
  3. 攔截器中若拋出異常需謹慎處理,避免破壞原有事務邊界。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved