2014-11-04 88 views
2

我有一個CDI bean,裏面有私有方法。我已經寫了一個攔截器,像下面:攔截CDI bean中的私有方法

攔截器的代碼:

@Interceptor 
@TimeMeasure 
public class TimeWatcher implements Serializable { 

    @AroundInvoke 
    public Object logMethodEntry(InvocationContext ctx) throws Exception { 

     long t0 = System.nanoTime(); 
     try { 
      return ctx.proceed(); 
     } finally { 
      long dt = System.nanoTime() - t0; 
      System.out.println("Method execution time: " + ctx.getMethod().getName() + " - " + dt); 
     } 
    } 
} 

註釋代碼:

import static java.lang.annotation.ElementType.METHOD; 
    import static java.lang.annotation.ElementType.TYPE; 
    import static java.lang.annotation.RetentionPolicy.RUNTIME; 


    @InterceptorBinding 
    @Target({TYPE, METHOD}) 
    @Retention(RUNTIME) 
    public @interface TimeMeasure { 

    } 

一切只爲這些外部調用的公共方法工作得很好,如果我叫方法從內CDI bean不起作用。我使用JSF 2.0 MyFaces和Omnifaces一起完成@ViewScoped

謝謝您提前。

回答

5

這是設計。內部呼叫永遠不會被攔截。

+0

非常感謝。你能說說你從哪裏知道嗎?我沒有在Oracle手冊中找到它。我是否必須閱讀規格才能瞭解這些細微差別? – Anatoly 2014-11-04 18:41:13

+1

我沒有這方面的規範/參考,但是對於CDI,您只能截取生命週期和業務方法,即對CDI bean的外部調用。攔截器通常由動態代理(裝飾器模式)實現 - 因此通常不會攔截內部調用。對於從你的bean中調用的公共方法,這應該/也可能會失敗(但可能依賴於實現)。關於這種「細微差別」,只要記住CDI/EJB bean的所有花哨的東西(事務,鎖定,攔截器)僅適用於外部調用。 – 2014-11-04 21:00:18