AspectJ 功能強大但需專用編譯器(ajc)與 IDE 支援,引入門檻高。AspectWerkz(AW)提供純 Java、無侵入、兩種運行模式:
javac 編譯,再以 awc (AspectWerkz Compiler) 二次處理位元碼,產出織入後的 class,可在任何 JDK 1.3+ JVM 直接運行,零運行時依賴,極易整合既有 Ant/Maven 建構流程。本文採離線模式,以 Tomcat + Servlet 為例完整示範。
| 術語 | 說明 |
|---|---|
| Cross-cutting Concern | 橫切關注點(如日誌、持久化、安全),散佈於多個業務模組 |
| Advice | 欲織入的邏輯程式碼(如環繞通知 AroundAdvice) |
| Pointcut | 定義織入位置的匹配規則(方法簽名模式) |
| Aspect | Pointcut + Advice 的組合 |
%ASPECTWERKZ_HOME%,加入 PATH。aspectwerkz.jar 放入 Tomcat common/lib 或 WebApp WEB-INF/lib。aspectwerkz.xml 放於 classpath 根目錄(建構時複製至 WEB-INF/classes)。package example;
public class AOPServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Person p = new Person();
p.setName(req.getParameter("name"));
p.setEmail(req.getParameter("email"));
req.setAttribute("person", p);
req.getRequestDispatcher("/view.jsp").forward(req, resp);
}
}
package example;
public class PersistenceAdvice extends AroundAdvice {
public Object execute(JoinPoint jp) throws Throwable {
MethodJoinPoint mjp = (MethodJoinPoint) jp;
Object result = jp.proceed(); // 先執行原方法
Object[] params = mjp.getParameters();
if (params[0] instanceof HttpServletRequest) {
HttpServletRequest req = (HttpServletRequest) params[0];
Person p = (Person) req.getAttribute("person");
if (p != null) {
new ContactManager().save(p, req.getRealPath("/") + "contacts.txt");
}
}
return result;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<aspectwerkz>
<advice-def name="persist" class="example.PersistenceAdvice" deployment-model="perJVM"/>
<aspect name="servlet">
<pointcut-def name="all" type="method" pattern="* example.*Servlet.doGet(..)"/>
<bind-advice pointcut="all">
<advice-ref name="persist"/>
</bind-advice>
</aspect>
</aspectwerkz>
Pattern 語法: 返回值類型 完整類別名.方法名(參數),* 通配任意返回值/參數,.. 通配任意參數列表。
javac -d WEB-INF/classes WEB-INF/src/*.javaaspectwerkz -offline aspectwerkz.xml WEB-INF/classes -cp %TOMCAT_HOME%/common/lib/servlet.jarSUCCESS: WEB-INF\classes 表示織入完成。瀏覽器提交表單 → Servlet 執行 → 切面攔截 doGet 返回後 → 自動持久化 Person 物件至 contacts.txt → 頁面正常轉向。原始 Servlet 完全不知持久化邏輯存在。
Tracing 介面)。AspectWerkz 離線模式以「標準編譯 + 後處理」極低門檻將 AOP 引入既有專案。十分鐘為全系統加入日誌、持久化、安全等橫切功能,無需修改業務代碼,真正實現關注點分離與演進式架構。