2013-03-11 13 views
0

我碰巧有一個@Aspect聲明一個被另一個方面的一個切入點攔截的方法。這些方面是通過編譯時編織創建的,而容器是使用Spring實例化的。在一個方面聲明一個方面

我註釋了我的方面@Configurable告訴Spring組件正在容器外創建。我碰巧在這方面也有一個靜態的參考對象Log。總之,代碼看起來像這樣

@Aspect 
@Configurable 
public class MyAspect { 
    private static final Log log = LogFactory.getClass(MyAspect.class); 
    // Autowired dependencies 

    // Pointcuts and advice 

    // Happens to be a pointcut of some other Advice 
    @Asynchronous 
    private Object someMethod(...) { 
    } 
} 

在AspectJ的編譯,我看不出我所期望的信息,這看起來是這樣的:

weaveinfo Join point 'method-call(java.lang.Object mypackage.someMethod(...))' in Type 'mypackage.MyAspect' (MyAspect.java:30) advised by around advice from 'anotherpackage.AsynchronousAspect' (from AsynchronousAspect.java)) 

正如預期的那樣,第三方諮詢從來沒有被調用過。不過,如果我添加了一個簡單的日誌條目,以我的意見,像

log.debug("Join point invoked!"); 

然後編譯正確執行,所有的方面有線(包括我第三方的依賴),並正確地調用。

添加日誌條目是否可以改變我的假設?

+0

我不知道這個設計。我喜歡方面,但如果你堅持這個方向,我會擔心過度複雜。一年後,我可以看到有人在撓撓頭,並說「他們在這裏想什麼?」有沒有更簡單的方法來做到這一點? – duffymo 2013-03-11 22:54:14

+0

它可能並不像聽起來那麼糟糕,如果你看到系統作爲一個整體,它可能更有意義爲什麼我要走這條路:)這兩個建議完全不相關。恰巧我依賴於使用aspectj的庫,而且我的方面取決於這個庫的功能。 – jabalsad 2013-03-11 23:01:54

+0

對我來說,如果將包含在'MyAspect'中的邏輯封裝在不同的類中,它會更乾淨。我傾向於將方面視爲切入點,而不是更多,允許您將實際邏輯打包爲更加可重用的組件。這樣你就不需要處理這個問題。 – 2013-03-13 00:48:16

回答

0

如果你知道自己在做什麼,你想要做的事情非常直截了當而且沒有危險。請道歉,我不是Spring用戶,並且我更喜歡AspectJ的本地語法到@AspectJ。這個小樣本運行良好:如預期

public class Application { 
    public static void main(String[] args) { 
     System.out.println("Hello world!"); 
     someMethod(); 
    } 

    private static void someMethod() { 
     System.out.println("Doing something ..."); 
    } 
} 
public aspect FirstAspect { 
    void around() : execution(void *..main(..)) { 
     System.out.println(thisJoinPointStaticPart + ": " + someMethod("before", "main")); 
     proceed(); 
     System.out.println(thisJoinPointStaticPart + ": " + someMethod("after", "main")); 
    } 

    private Object someMethod(String position, String methodName) { 
     return position + " " + methodName; 
    } 
} 
public aspect SecondAspect { 
    Object around() : execution(* *..someMethod(..)) { 
     System.out.println(thisJoinPointStaticPart + ": before someMethod"); 
     Object result = proceed(); 
     System.out.println(thisJoinPointStaticPart + ": after someMethod"); 
     return result; 
    } 
} 

結果:

execution(Object FirstAspect.someMethod(String, String)): before someMethod 
execution(Object FirstAspect.someMethod(String, String)): after someMethod 
execution(void Application.main(String[])): before main 
Hello world! 
execution(void Application.someMethod()): before someMethod 
Doing something ... 
execution(void Application.someMethod()): after someMethod 
execution(Object FirstAspect.someMethod(String, String)): before someMethod 
execution(Object FirstAspect.someMethod(String, String)): after someMethod 
execution(void Application.main(String[])): after main 

如果還您關心的哪些方面應用/執行,thhe爲了請使用declare precedence

如果您在訪問時遇到問題,例如私人會員,您需要使用privileged aspect

更新:更改了使用thisEnclosingJoinPointStaticPartthisJoinPointStaticPart。這只是一個複製&粘貼錯誤。結果與execution連接點上的結果相同,但無論如何,更正顯示代碼的意圖更好。