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

JBoss EJB 3.0 Interceptor 完整實戰:從類別級到方法級攔截

     編輯:Java 相關知識

Interceptor 核心概念

Interceptor (攔截器) 可在方法呼叫前後執行橫切邏輯:日誌、效能監控、安全檢查、交易管理等。EJB 3.0 基於註解,零配置檔即可啟用。

範例架構

  • Hello : 遠端/本地介面
  • HelloBean : 無狀態 Session Bean,含業務方法與類內部攔截器
  • TracingInterceptor : 外部獨立攔截器類別
  • Client : JNDI 查找並呼叫

1. 定義業務介面

@Remote public interface HelloRemote extends Hello {}
@Local  public interface HelloLocal  extends Hello {}

public interface Hello {
    void hello();
    String hello2();
}

2. Bean 實作:雙重攔截示範


@Stateless
@Interceptors({TracingInterceptor.class}) // 類別級:外部攔截器
public class HelloBean implements HelloRemote, HelloLocal {

    public void hello() { System.out.println("Hello roson"); }
    public String hello2() { return "are you ok"; }

    // === 方法級:Bean 內部攔截器 (針對特定方法) ===
    @AroundInvoke
    public Object myBeanInterceptor(InvocationContext ctx) throws Exception {
        String m = ctx.getMethod().getName();
        if ("hello".equals(m)) System.out.println("*** hello: ");
        if ("hello2".equals(m)) System.out.println("*** hello2: ");
        return ctx.proceed(); // 必須呼叫,否則業務方法不執行
    }
}

3. 外部攔截器類別:通用追蹤邏輯


public class TracingInterceptor {
    @AroundInvoke
    public Object log(InvocationContext ctx) throws Exception {
        System.out.println("*** TracingInterceptor intercepting");
        long start = System.currentTimeMillis();
        try {
            return ctx.proceed();
        } finally {
            long time = System.currentTimeMillis() - start;
            String method = ctx.getTarget().getClass().getName() 
                          + "." + ctx.getMethod().getName() + "()";
            System.out.println("*** " + method + " took " + time + "ms");
        }
    }
}

關鍵 API:InvocationContext

方法用途
getMethod()取得被攔截的 java.lang.reflect.Method
getTarget()取得目標 Bean 實例 (可轉型呼叫業務方法)
getParameters() / setParameters()讀取/修改方法參數
getContextData()攔截器鏈間傳遞資料的 Map
proceed()執行下一個攔截器或目標方法,**必須呼叫**

4. 客戶端呼叫:完全感知不到攔截器


public class Client {
    public static void main(String[] args) throws Exception {
        InitialContext ctx = new InitialContext();
        Hello hello = (Hello) ctx.lookup(HelloRemote.class.getName());
        hello.hello();
        System.out.println(hello.hello2());
    }
}

輸出順序示例

*** TracingInterceptor intercepting
*** hello: 
Hello roson
*** TracingInterceptor invocation of HelloBean.hello() took 5ms
*** TracingInterceptor intercepting
*** hello2: 
*** TracingInterceptor invocation of HelloBean.hello2() took 2ms
are you ok

部署與執行 (JBoss EJB 3.0 Preview 5)

  1. 啟動 JBoss: run.bat -c all
  2. Ant 建置: ant build → ant run
  3. 需 log4j.properties 避免「No appenders」警告 (文中附有範例)。

多攔截器順序控制


@Interceptors({FirstInterceptor.class, SecondInterceptor.class})
@Stateless
public class MyBean { ... }

執行順序:First → Second → Bean 內部 @AroundInvoke → 目標方法。

總結

  • 類別級 (@Interceptors):通用橫切關注 (日誌、審計、安全)。
  • 方法級 (@AroundInvoke):針對特定方法的精細控制 (參數驗證、快取)。
  • 外部類別 可重用,內部方法 便於存取 Bean 狀態。
  • 客戶端零侵入,完美符合 AOP 精神。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved