OOP 以物件為核心,但隨系統擴大,交叉關注點(事務、安全、日誌、快取)散落於多模組,若以「複製貼上」或顯式呼叫輔助方法,維護成本極高。AOP 讓開發者只定義切入點與增強邏輯,框架自動織入,業務碼零修改,極大提升擴展性。
AspectJ 使用 aspect 關鍵字定義切面,ajc 編譯器在編譯期將增強織入目標類別產生新的 .class。範例:TxAspect 環繞 Hello.sayHello() 印出事務開啟/結束,LogAspect 在方法後記錄日誌。反編譯顯示 Hello.class 已包含 AspectJ 產生的輔助方法與調用,證明編譯時增強。優點:執行期無額外開銷;缺點:需專用編譯器與織入器。
Spring 採用運行時在記憶體動態生成代理類別,無需特殊編譯器。啟用 <aop:aspectj-autoproxy/> 或 AnnotationAwareAspectJAutoProxyCreator 後,標註 @Aspect 的 Bean 會被識別為切面,Spring 容器自動為目標 Bean 生成代理。
java.lang.reflect.Proxy + InvocationHandler),代理類別名如 $Proxy7。Chinese$$EnhancerByCGLIB$$290441d2。此選擇對開發者透明,符合「面向介面程式設計」原則時優先走 JDK 代理。
代理方法 = 增強處理 + 回調目標方法。框架根據切入點決定在代理方法何處織入 Before/After/Around/AfterReturning/AfterThrowing 增強。IoC 容器管理代理與目標的依賴關係,代理可直接注入其他 Bean。
CGLIB(Code Generation Library)運行時動態生成子類。步驟:
MethodInterceptor(如 AroundAdvice),在 intercept 中執行目標方法(proxy.invokeSuper)前後織入邏輯。Enhancer 設定目標類別(setSuperclass)與攔截器(setCallback),呼叫 create() 取得代理實例。測試證明 CGLIB 代理行為與 Spring AOP 產生的 CGLIB 代理一致,驗證 Spring AOP 底層即委託 CGLIB。