如何从切入点中排除匿名内部方法?

Ian*_*Ian 6 java aop aspectj

我有一个AspectJ跟踪例程设置为使用以下切入点记录方法进入和退出条件:

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

在我的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);
    ...
Run Code Online (Sandbox Code Playgroud)

这很好,除了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]
Run Code Online (Sandbox Code Playgroud)

我补充说相当广泛

&& !within( is(AnonymousType) )
Run Code Online (Sandbox Code Playgroud)

条件切入点,如上所示,但它没有效果.事实上,我很难找到(AnonymousType)在任何地方记录.

我如何编写一个排除这种匿名内部方法的切入点,最好不要影响其他方法?

Ian*_*Ian 4

这个答案是 Andrew Clement 提供的(请参阅http://dev.eclipse.org/mhonarc/lists/aspectj-users/msg14906.html,ff),经他许可重新发布在这里:

\n\n

access$0 方法已添加到 MailMail 中,因为日志在 MailMail 中是私有的 - 它使 log.debug(line) 能够从匿名类(大概称为 MailMail$1)访问日志。

\n\n

认识到这一点,我们可以看到 access$0 不在匿名类中,它是在 MailMail 类中生成的访问器,因此您的附加切入点片段不起作用。

\n\n

几个选项:

\n\n

具体排除它:

\n\n
pointcut anyMethodExecuted():       execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace) && !execution(* MailMail.access$0(..));\n
Run Code Online (Sandbox Code Playgroud)\n\n

排除所有合成访问器(它被认为是合成的,因为它是由编译器生成的 \xe2\x80\x98\xe2\x80\x99 以支持您正在执行的操作):

\n\n
pointcut anyMethodExecuted():       execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace) && !execution(synthetic * access$*(..));\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者你可以排除所有合成物:

\n\n
pointcut anyMethodExecuted():       execution (!synthetic * biz.ianw.lanchecker.*.*(..)) && !within(Trace);\n
Run Code Online (Sandbox Code Playgroud)\n