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

Spring AOP 靜態代理模式詳解與程式碼實作

     編輯:Java 綜合教學

Spring AOP 靜態代理模式詳解與程式碼實作

靜態代理是 AOP 最基礎的形式:代理類在編譯期就已確定,直接包裝目標物件。雖然 Spring 實際運行使用動態代理,但理解靜態代理有助於掌握 AOP 核心概念——核心業務與橫切關注點分離。

一、AOP 核心概念

  • 切面:將分散在多處的非核心邏輯(日誌、事務、權限)封裝為可重用模組。
  • 目標物件:核心業務類(如 Student)。
  • 代理物件:攔截目標方法,執行前置/後置增強,再委派目標方法。

二、靜態代理特點

  1. 代理類必須實作與目標類相同的介面。
  2. 代理類透過建構子接收目標物件引用(組合)。
  3. 每個目標方法都需在代理類中手寫增強邏輯,程式碼冗餘、維護困難。

三、完整程式碼範例:高三學生與家長代理

1. 共同介面

package aop_001;

public interface G3Student {
    void studyAtHome(String core);
    void studyAtSchool(String core);
}

2. 目標類:高三男生

package aop_001;

public class G3Student_boy implements G3Student {
    @Override
    public void studyAtHome(String core) {
        System.out.println(core + "在 HOME 學習");
    }

    @Override
    public void studyAtSchool(String core) {
        System.out.println(core + "在 SCHOOL 學習");
    }
}

3. 代理類:家長(靜態代理)

package aop_001;

public class G3Student_proxy implements G3Student {
    private G3Student student; // 組合目標介面

    public G3Student_proxy(String sex) {
        if ("boy".equals(sex)) {
            student = new G3Student_boy();
        } else {
            student = new G3Student_girl(); // 假設存在
        }
    }

    @Override
    public void studyAtHome(String core) {
        // 前置增強:準備飯菜
        System.out.println("代理:準備買菜");
        System.out.println("代理:準備洗菜");
        System.out.println("代理:準備炒菜");
        System.out.println("代理:準備煮飯");
        System.out.println("-----------------");

        student.studyAtHome(core); // 委派核心業務

        // 後置增強:準備補品
        System.out.println("-----------------");
        System.out.println("代理:購買補品");
        System.out.println("代理:熬製補品");
        System.out.println("代理:加入佐料");
        System.out.println();
    }

    @Override
    public void studyAtSchool(String core) {
        // 相同增強邏輯重複出現 → 程式碼冗餘
        System.out.println("代理:準備買菜");
        System.out.println("代理:準備洗菜");
        System.out.println("代理:準備炒菜");
        System.out.println("代理:準備煮飯");
        System.out.println("-----------------");

        student.studyAtSchool(core);

        System.out.println("-----------------");
        System.out.println("代理:購買補品");
        System.out.println("代理:熬製補品");
        System.out.println("代理:加入佐料");
        System.out.println();
    }
}

4. 測試類

package aop_001;

public class Test {
    public static void main(String[] args) {
        G3Student proxy = new G3Student_proxy("boy");
        proxy.studyAtHome("小明");
        proxy.studyAtSchool("小明");
    }
}

四、輸出結果

代理:準備買菜
代理:準備洗菜
代理:準備炒菜
代理:準備煮飯
-----------------
小明在 HOME 學習
-----------------
代理:購買補品
代理:熬製補品
代理:加入佐料

代理:準備買菜
代理:準備洗菜
代理:準備炒菜
代理:準備煮飯
-----------------
小明在 SCHOOL 學習
-----------------
代理:購買補品
代理:熬製補品
代理:加入佐料

五、靜態代理缺點總結

  • 每個目標方法都需在代理類重寫增強邏輯,違反 DRY 原則。
  • 新增目標方法需同步修改代理類,耦合度高。
  • 無法統一管理橫切關注點(如想修改日誌格式,需改所有代理類)。

這正是動態代理(JDK Proxy / CGLIB)與 Spring AOP 要解決的問題:在執行期動態生成代理,將增強邏輯集中在切面中,實現真正的關注點分離。下一篇將詳細介紹動態代理實作。

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