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

Spring AOP 原理與 CGLIB 動態代理深度解析

     編輯:Java 相關知識

AOP 存在的價值

OOP 以物件為核心,但隨系統擴大,交叉關注點(事務、安全、日誌、快取)散落於多模組,若以「複製貼上」或顯式呼叫輔助方法,維護成本極高。AOP 讓開發者只定義切入點與增強邏輯,框架自動織入,業務碼零修改,極大提升擴展性。

AspectJ 編譯時增強

AspectJ 使用 aspect 關鍵字定義切面,ajc 編譯器在編譯期將增強織入目標類別產生新的 .class。範例:TxAspect 環繞 Hello.sayHello() 印出事務開啟/結束,LogAspect 在方法後記錄日誌。反編譯顯示 Hello.class 已包含 AspectJ 產生的輔助方法與調用,證明編譯時增強。優點:執行期無額外開銷;缺點:需專用編譯器與織入器。

Spring AOP 運行時動態代理

Spring 採用運行時在記憶體動態生成代理類別,無需特殊編譯器。啟用 <aop:aspectj-autoproxy/> 或 AnnotationAwareAspectJAutoProxyCreator 後,標註 @Aspect 的 Bean 會被識別為切面,Spring 容器自動為目標 Bean 生成代理。

代理生成策略

  • 目標類別實作介面 → 使用 JDK 動態代理(java.lang.reflect.Proxy + InvocationHandler),代理類別名如 $Proxy7。
  • 目標類別未實作介面 → 使用 CGLIB 繼承目標類別生成子類,代理類別名如 Chinese$$EnhancerByCGLIB$$290441d2。

此選擇對開發者透明,符合「面向介面程式設計」原則時優先走 JDK 代理。

Spring AOP 實現原理剖析

代理方法 = 增強處理 + 回調目標方法。框架根據切入點決定在代理方法何處織入 Before/After/Around/AfterReturning/AfterThrowing 增強。IoC 容器管理代理與目標的依賴關係,代理可直接注入其他 Bean。

手動使用 CGLIB 生成代理

CGLIB(Code Generation Library)運行時動態生成子類。步驟:

  1. 實作 MethodInterceptor(如 AroundAdvice),在 intercept 中執行目標方法(proxy.invokeSuper)前後織入邏輯。
  2. 使用 Enhancer 設定目標類別(setSuperclass)與攔截器(setCallback),呼叫 create() 取得代理實例。

測試證明 CGLIB 代理行為與 Spring AOP 產生的 CGLIB 代理一致,驗證 Spring AOP 底層即委託 CGLIB。

小結

  • AspectJ:編譯時增強,效能佳,需專用工具鏈。
  • Spring AOP:運行時動態代理,開發便利,每次啟動需生成代理,效能略遜。
  • 代理生成核心:JDK 代理(介面基礎)與 CGLIB(繼承基礎),Spring 自動選擇。
  • 理解動態代理機制有助於排查 AOP 不生效、效能分析與自定義代理場景。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved