靜態代理是 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;
}
@Aspect + @Before/@After 宣告式切面,底層即封裝了 JDK 動態代理與 CGLIB。MethodInterceptor、Pointcut、Advisor 概念,實現精準的切入點匹配。Subject),不可轉為實作類(RealSubject)。equals/hashCode 若未正確重寫,集合去重、Map 鍵值查找會出現異常行為(範例中 RealSubject 的 equals 邏輯有缺陷,僅作演示)。