面向切面程式設計(AOP)非取代 OOP,而是補足 OOP 在「橫切關注點」上的不足:日誌、安全、交易、效能監控等邏輯分散在無數業務類別中,導致程式碼糾纏、難以維護。AOP 將這些橫切邏輯模組化為切面,透過切入點精準織入目標連接點,實現關注點分離。
jboss-aop.jar、javassist.jar、自訂 ClassLoaderpublic class TracingInterceptor implements Interceptor {
public String getName() { return "TracingInterceptor"; }
public InvocationResponse invoke(Invocation inv) throws Throwable {
String msg = "";
if (inv.getType() == InvocationType.METHOD) {
msg = "method: " + MethodInvocation.getMethod(inv).getName();
} else if (inv.getType() == InvocationType.CONSTRUCTOR) {
msg = "constructor: " + ConstructorInvocation.getConstructor(inv);
} else { return inv.invokeNext(); } // 忽略欄位存取
System.out.println("Entering " + msg);
InvocationResponse rsp = inv.invokeNext(); // 執行真實目標
System.out.println("Leaving " + msg);
return rsp;
}
}
<aop>
<interceptor-pointcut class="POJO">
<interceptors><interceptor class="TracingInterceptor"/></interceptors>
</interceptor-pointcut>
</aop>
class=".*" 可攔截所有類別;com.mypkg.* 限定套件。
<class-metadata group="tracing" class="POJO">
<method name="(get.*)|(set.*)"><filter>true</filter></method>
<method name="main"><filter>true</filter></method>
</class-metadata>
String filter = (String) inv.getMetaData("tracing", "filter");
if ("true".equals(filter)) return inv.invokeNext();
public interface Tracing { void enableTracing(); void disableTracing(); }
public class TracingMixin implements Tracing {
private Advised advised;
public TracingMixin(Object obj) { this.advised = (Advised) obj; }
public void enableTracing() {
advised._getInstanceAdvisor().getMetaData().addMetaData("tracing", "filter", false);
}
public void disableTracing() {
advised._getInstanceAdvisor().getMetaData().addMetaData("tracing", "filter", true);
}
}
<introduction-pointcut class="POJO">
<mixin>
<interfaces>Tracing</interfaces>
<class>TracingMixin</class>
<construction>new TracingMixin(this)</construction>
</mixin>
</introduction-pointcut>
POJO pojo = new POJO();
Tracing t = (Tracing) pojo; // 強轉成功,因引入已實作介面
pojo.helloWorld();
t.disableTracing(); pojo.helloWorld(); // 不印追蹤
t.enableTracing(); pojo.helloWorld(); // 印追蹤
export CLASSPATH=.:jboss-common.jar:jboss-aop.jar:javassist.jar
javac *.java
java -Djava.system.class.loader=org.jboss.aop.standalone.SystemClassLoader POJO
JBoss AOP 展示了純 Java 實現 AOP 的完整能力:攔截器處理橫切邏輯、元資料提供聲明式配置、引入實現動態型別擴展、切入點精準編織。現代 Spring AOP、AspectJ 雖語法更優雅,但核心概念一脈相承。掌握本文四大構件,即可駕馭主流 AOP 框架。