面向對象編程(OOP)擅長將問題領域的「名詞」映射為軟體系統中的對象,自然地完成從業務到代碼的轉換。然而,現實開發中總有些需求無法用簡單的對象層級來描述。例如:系統中散佈在 40 多個類別的方法都需要進行權限檢驗。若採用傳統繼承方式,需建立基類或介面,再讓所有相關類別繼承,一旦需求變更,修改將分散在數十個文件中,極大增加出錯風險與維護成本。
這類跨越典型職責邊界、散佈於多個模組的行為——如權限檢驗、日誌記錄、事務管理、錯誤處理——被稱為「橫切關注點」。缺乏模組化支持導致開發者難以邏輯思維、實現與變更這類行為。
AOP(Aspect Oriented Programming,面向切面編程)是 GoF 設計模式的延續,旨在解耦調用者與被調用者。它專門解決 OOP 與過程式方法難以處理的橫切問題(事務、安全、日誌等)。當系統複雜度上升、橫切關注點成為瓶頸時,AOP 能輕鬆化解。

圖 1:將模組作為一批關注點實現
AOP 補充而非取代 OOP。OOP 在常規場景表現良好,但在需為多對象、多方法套用相同行為(如事務)時顯得無力——只能重複複製貼上代碼。AOP 引入「切入點」概念,讓開發者從新角度思考程式結構:若需對一組方法施加橫切行為,應攔截這些方法而非侵入業務邏輯。
在 J2EE 開發中,AOP 的攔截能力提供了「在任何對象方法調用前/後加入自定義行為」的手段,可處理企業應用中的橫切關注點,同時保持強類型(無需改變方法簽名)。

圖 2:權限控制的 J2EE 容器實現
J2EE 規範早於 AOP 提供容器級權限標準,利用 JDK 1.3+ 動態代理 API 將原本分散在應用層的 Proxy 上移至容器層。這大幅簡化應用設計,將權限關注分離為容器配置工作。但容器級實現靈活性、可擴展性受限;雖 JBoss 4.0 引入 AOP 讓開發者能操縱容器行為,卻綁定特定容器,移植風險大。
有了 AOP,業務方法回歸純粹:
public someFunction() {
// do the business method
// ...
}
將權限操作封裝為 Advice,配置 Advisor 關注所有業務方法(如特定 package),剩下交給 RBAC 與 AOP 完成。這實現了縱向業務邏輯與橫切權限關注的徹底分離。
public class PermissionCheckAdvice implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable {
// 權限判斷
if (!this.getContext().getUser().canExecute(this, method)) {
throw new PermissionDeniedException();
}
}
}
上下文(Context)或當前 User 通過 IoC(依賴注入)反向傳入。初始化工作可在 SuperServlet 中完成,以 Session 單例形式保存。
<beans>
<!-- Bean configuration -->
<bean id="businesslogicbean"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>IBusinessLogic</value>
</property>
<property name="target">
<ref local="beanTarget"/>
</property>
<property name="interceptorNames">
<list>
<value>thePermissionCheckBeforeAdvisor</value>
</list>
</property>
</bean>
<!-- Bean Classes -->
<bean id="beanTarget" class="BusinessLogic">
<property name="user"><<YOUR USER OBJECT>> </property>
</bean>
<!-- Advisor pointcut definition for before advice -->
<bean id="thePermissionCheckBeforeAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="thePermissionCheckBeforeAdvice"/>
</property>
<property name="pattern">
<value>.*</value>
</property>
</bean>
<!-- Advice classes -->
<bean id="thePermissionCheckBeforeAdvice"
class="PermissionCheckBeforeAdvice"/>
</beans>
AOP 引入 Aspect,將影響多類的行為封裝為可重用模組,實現橫切關注點模組化,消除 OOP 導致的代碼混亂與分散,提升系統可維護性與代碼重用性。利用 AOP 攔截能力,我們在不修改方法簽名的前提下,優雅地解耦了業務功能與權限檢驗,為企業級應用提供了清晰、可擴展的權限控制方案。