2014-09-05 15 views
0

我正在實現一個審計api來記錄其聲明中有一個@Auditable註解的任何方法調用。基本要求是它必須被當前的應用程序使用,並且應該是非侵入性的。我已經通過Log4J2包裝器獲得了審計API,並且還成功地將它用在了一些EJB攔截器中。然而,我需要創建一個全地形攔截器,我可以在任何使用註釋的地方使用它,也就是說,我想用它註釋servlet,EJB和POJO方法,並讓攔截器發揮它的魔力。需要在普通的java(ee,servlets和POJOs)中創建方法攔截器以在weblogic中使用,我可以使用什麼來實現呢?

我試過Java EE攔截器,它們只能在EJB中工作,我試過GUICE,但它不能用於servlet或EJB方法,只有guice注入了POJO。

我想知道,如果有人知道如何,我應該使用什麼,如果可以指出一個例子,我會成爲rategull。

非常感謝。

+2

AspectJ,但取決於你對「非侵入性」的解釋 – 2014-09-06 00:10:31

+0

嗯,這很像「將註釋放在方法中並忘記它」。對於遺留應用程序,我不確定AspecJ會發生什麼情況。 – EdwinF 2014-09-10 16:20:31

+0

即使您沒有源文件,AspectJ也可以處理遺留應用程序。 – 2014-09-10 18:01:40

回答

1

一個可能的解決方案是使用AspectJ。 AspectJ可以讓你定義你想要攔截的東西(所謂的連接點)並在發生時執行你想要的代碼(所謂的建議)。

連接點可以是一切,但在你的情況下,你需要用給定的註釋來捕獲方法的執行,所以我們將只使用「執行」連接點。

AspectJ然後需要檢測你的類。這是可以做到:

  1. 編譯代碼與AspectJ編譯器,它擴展了Java編譯器有什麼需要
  2. 「織」現有的jar文件,這樣你就可以正常的構建過程之後做到這一點,或者你甚至可以在沒有源文件的jar文件中執行它(這種情況並非如此,因爲無論如何您都需要放置註釋)。

我們將使用第一種方法只編譯方面,第二種方法來測試你想要的jar文件或類文件夾。

要做到這一點,您需要編寫一個必須具有運行時保留的註釋,可審覈的。

然後你寫一個方面:

public aspect Audit { // An aspect then compiles as if it was a class (at runtime, it is a normal class) 

    Object around() : // This is an around advice 
    execution(@Auditable * *(..)) // Here you're catching execution of any method of any class with any parameter and any return type, which is annotated with @Auditable 
    { 
    // Do what you want to do before the method 
    long start = System.nanoTime(); 
    Logger.log("I'm entering into " + thisJoinPoint); // with thisJoinPoint you can extract a lot of informations, like what class, what method, what parameters, on which instance etc.. 
    try { 
     Object ret = proceed(); // "proceed" goes on executing the method 
     // You could log, or do whatever you want with the return value, which could be "Void". 
     return ret; 
    } finally { 
     Logger.log("It took ns: " + (System.nanoTime() - start)); 
    } 
    } 

} 

一旦你寫了這方面(通常在一個包,並以「.aj」擴展,但不是強制性的),你用AspectJ編譯器編譯。

ajc -outxml -classpath thisLib.jar:thatLib.jar -1.5 -outjar auditableAspect.jar package/of/your/AuditableAspect.aj 

這與使用javac編譯java代碼很相似。在類路徑上,你需要編譯方面所需的東西,在這個例子中,我使用了一個神祕的Logger,它必須位於thisLis.jar或thatLib.jar中。

最後,您將擁有一個auditableAspect.jar文件,該文件將包含您方面的已編譯類。

現在,要使用它,您需要「編織」您希望它「截取」的類(或jar文件)。要做到這一點,仍然與濃縮蘋果汁命令:

ajc -inpath myStuff.jar -outjar myStuffAudited.jar -aspectPath auditableAspect.jar 

然後,您會在的MyStuff myStuffAudited.jar相同的類找到。jar和其他一些合成的內部匿名類。

現在基本上你可以從你的應用程序類路徑(或WEB-INF/lib,如果它是一個web應用程序)中移除myStuff.jar,用myStuffAudited.jar替換它,並且添加auditableAspect.jar,這是你的aspect和aspectjrt .jar這是AspectJ運行時。

重新加載你的應用程序,它將開始記錄。

您可以在所有需要的罐子上或在for循環中的所有罐子上做到這一點;那些未受影響的將不受影響。

這可以在您的構建週期中以多種方式進行集成。

  • 顯然,.BAT或.sh腳本可以自動執行它
  • Ant有任務的AspectJ
  • Maven有更多瞭解AspectJ插件
  • Eclipse有編制和IDE
  • 內編織一個插件

不知道你是如何建立你的項目,所以YMMV。

這是侵入與否,這是一個意見;但據我所知,沒有太多的軟件包提供運行時審計,而不用某種方式操縱類字節碼,如果不使用有限的(如你所見)接口的運行時代理。

還有一個選項可以使用編織類加載器,這將完全消除編織現有的jar和類的需要,因爲它們會在加載時由類加載器本身編織。它工作得很好,我喜歡它,但它取決於您的運行時環境。

+0

精彩的回答,非常感謝。我將它標記爲已回答,因爲它基本上是我正在尋找的。謝謝Simone。 – EdwinF 2014-11-25 19:35:16

相關問題