首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

AspectWerkz AOP 實戰指南:離線編譯模式打造輕量級切面應用

     編輯:Java 相關知識

前言:為何選擇 AspectWerkz?

AspectJ 功能強大但需專用編譯器(ajc)與 IDE 支援,引入門檻高。AspectWerkz(AW)提供純 Java、無侵入、兩種運行模式:

  • 線上模式: 自定 ClassLoader 於類別載入期即時織入位元碼,無需預編譯,但需應用伺服器配置支援。
  • 離線模式: 先 javac 編譯,再以 awc (AspectWerkz Compiler) 二次處理位元碼,產出織入後的 class,可在任何 JDK 1.3+ JVM 直接運行,零運行時依賴,極易整合既有 Ant/Maven 建構流程。

本文採離線模式,以 Tomcat + Servlet 為例完整示範。

核心術語速查

術語說明
Cross-cutting Concern橫切關注點(如日誌、持久化、安全),散佈於多個業務模組
Advice欲織入的邏輯程式碼(如環繞通知 AroundAdvice)
Pointcut定義織入位置的匹配規則(方法簽名模式)
AspectPointcut + Advice 的組合

安裝與環境準備

  1. 下載 AspectWerkz,解壓至 %ASPECTWERKZ_HOME%,加入 PATH。
  2. 將 aspectwerkz.jar 放入 Tomcat common/lib 或 WebApp WEB-INF/lib。
  3. 專案結構:aspectwerkz.xml 放於 classpath 根目錄(建構時複製至 WEB-INF/classes)。

範例應用:Servlet + 持久化切面

1. 業務 Servlet(純淨、無持久化邏輯)

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);
    }
}

2. 定義 Advice:環繞通知實作持久化

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;
    }
}

3. aspectwerkz.xml:綁定 Pointcut 與 Advice

<?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 語法: 返回值類型 完整類別名.方法名(參數),* 通配任意返回值/參數,.. 通配任意參數列表。

離線編譯與部署流程

  1. javac -d WEB-INF/classes WEB-INF/src/*.java
  2. aspectwerkz -offline aspectwerkz.xml WEB-INF/classes -cp %TOMCAT_HOME%/common/lib/servlet.jar
  3. 輸出 SUCCESS: WEB-INF\classes 表示織入完成。
  4. 打包 WAR 部署 Tomcat,啟動驗證。

效果驗證

瀏覽器提交表單 → Servlet 執行 → 切面攔截 doGet 返回後 → 自動持久化 Person 物件至 contacts.txt → 頁面正常轉向。原始 Servlet 完全不知持久化邏輯存在。

進階特性預覽

  • Introduction: 動態為類別新增介面/方法(如 Tracing 介面)。
  • Metadata: XML 定義方法層級屬性(交易、安全),Advice 讀取決策。
  • 線上模式: 開發期熱部署、無需重編譯,適合快速迭代。

結語

AspectWerkz 離線模式以「標準編譯 + 後處理」極低門檻將 AOP 引入既有專案。十分鐘為全系統加入日誌、持久化、安全等橫切功能,無需修改業務代碼,真正實現關注點分離與演進式架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved