2015-11-06 56 views
6

我有一個AspectJ跟蹤常規設置使用以下切入點登錄方法進入和退出條件:如何從切入點中排除匿名內部方法?

public aspect Trace {  
    pointcut anyMethodExecuted():  execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace) && !within(is(AnonymousType)); 
    pointcut anyConstructorExecuted(): execution (biz.ianw.lanchecker.*.new(..)) && !within(Trace); 

在我sendEmail類我有一個調用setDebugOut方法來調試輸出重定向到一個LogOutputStream的方法:

final private static Logger log = LoggerFactory.getLogger(MailMail.class); 
... 
LogOutputStream losStdOut = new LogOutputStream() {    
    @Override 
    protected void processLine(String line, int level) { 
     log.debug(line); 
    } 
};  

public void sendPlainHtmlMessage(...) { 
    Session session = javaMailSender.getSession(); 
    PrintStream printStreamLOS = new PrintStream(losStdOut); 
    session.setDebugOut(printStreamLOS); 
    ... 

能正常工作,不同之處在於Trace類切入點攔截該呼叫的匿名內部類,產生作爲輸出:

20:14:18.908 TRACE [biz.ianw.lanchecker.Trace] - Enters method: Logger biz.ianw.lanchecker.MailMail.access$0() 
20:14:18.909 TRACE [biz.ianw.lanchecker.Trace] - Exits method: Logger biz.ianw.lanchecker.MailMail.access$0(). 
20:14:18.909 TRACE [biz.ianw.lanchecker.Trace] - with return value: Logger[biz.ianw.lanchecker.MailMail] 
20:14:18.909 DEBUG [biz.ianw.lanchecker.MailMail] - DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle] 

我添加而過於寬泛

&& !within(is(AnonymousType)) 

條件切入點,如上所示,但它沒有作用。事實上,我真的很難找到(AnonymousType)記錄在任何地方。

我該如何編寫一個排除此匿名內部方法的切入點,最好不影響任何其他方法?

+0

不知道這是否相關? ''getPoint.getStaticPart()。getSignature()。getDeclaringType()。isAnonymousClass()''返回'False'爲'... access $ 0()'。 'toLongString()'將方法簽名顯示爲:'execution(static org.slf4j.Logger biz.ianw.lanchecker.MailMail.access $ 0())' – Ian

回答

3

這個答案是禮貌安德魯·克萊門特(見http://dev.eclipse.org/mhonarc/lists/aspectj-users/msg14906.html,FF),轉貼在這裏與他的許可:

訪問$ 0法的研究已經被添加到MailMail因爲日誌中MailMail是私有的 - 它使log.debug(行)從匿名類訪問日誌(大概稱爲MailMail $ 1)。

認識到,我們可以看到訪問$ 0不在匿名類中,它是一個在MailMail類中生成的訪問器,因此您的附加切入點片段無法工作。

兩個選擇:

明確排除:

pointcut anyMethodExecuted():  execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace) && !execution(* MailMail.access$0(..)); 

排除所有合成的訪問器(它被認爲是合成的,因爲它是「產生」由編譯器來支持你在做什麼):

pointcut anyMethodExecuted():  execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace) && !execution(synthetic * access$*(..)); 

或者你可以排除所有合成纖維也許是:

pointcut anyMethodExecuted():  execution (!synthetic * biz.ianw.lanchecker.*.*(..)) && !within(Trace);