如何从切入点中排除匿名内部方法?
How to exclude an anonymous inner method from a pointcut?
我有一个 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 class 中,我有一个调用 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 class 切入点拦截匿名内部 class 的调用,产生输出:
20:14:18.908 TRACE [biz.ianw.lanchecker.Trace] - Enters method: Logger biz.ianw.lanchecker.MailMail.access[=12=]()
20:14:18.909 TRACE [biz.ianw.lanchecker.Trace] - Exits method: Logger biz.ianw.lanchecker.MailMail.access[=12=]().
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) )
切入点的条件,如上所示,但没有效果。事实上,我很难找到在任何地方记录的 is(AnonymousType)。
如何编写排除此匿名内部方法的切入点,最好不影响任何其他方法?
此回答由 Andrew Clement 提供(参见 http://dev.eclipse.org/mhonarc/lists/aspectj-users/msg14906.html, ff),经他许可转载于此:
access$0 方法已添加到 MailMail,因为日志在 MailMail 中是私有的 - 它使 log.debug(行)能够从匿名 class(可能称为 MailMail$1)访问日志。
认识到这一点,我们可以看到 access$0 不在匿名 class 中,它是在 MailMail class 中生成的访问器,因此您的附加切入点片段不起作用。
几个选项:
具体排除:
pointcut anyMethodExecuted(): execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace) && !execution(* MailMail.access[=10=](..));
排除所有合成访问器(它被认为是合成的,因为它是由编译器“生成”以支持您正在做的事情):
pointcut anyMethodExecuted(): execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace) && !execution(synthetic * access$*(..));
或者您可以排除所有合成材料:
pointcut anyMethodExecuted(): execution (!synthetic * biz.ianw.lanchecker.*.*(..)) && !within(Trace);
我有一个 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 class 中,我有一个调用 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 class 切入点拦截匿名内部 class 的调用,产生输出:
20:14:18.908 TRACE [biz.ianw.lanchecker.Trace] - Enters method: Logger biz.ianw.lanchecker.MailMail.access[=12=]()
20:14:18.909 TRACE [biz.ianw.lanchecker.Trace] - Exits method: Logger biz.ianw.lanchecker.MailMail.access[=12=]().
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) )
切入点的条件,如上所示,但没有效果。事实上,我很难找到在任何地方记录的 is(AnonymousType)。
如何编写排除此匿名内部方法的切入点,最好不影响任何其他方法?
此回答由 Andrew Clement 提供(参见 http://dev.eclipse.org/mhonarc/lists/aspectj-users/msg14906.html, ff),经他许可转载于此:
access$0 方法已添加到 MailMail,因为日志在 MailMail 中是私有的 - 它使 log.debug(行)能够从匿名 class(可能称为 MailMail$1)访问日志。
认识到这一点,我们可以看到 access$0 不在匿名 class 中,它是在 MailMail class 中生成的访问器,因此您的附加切入点片段不起作用。
几个选项:
具体排除:
pointcut anyMethodExecuted(): execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace) && !execution(* MailMail.access[=10=](..));
排除所有合成访问器(它被认为是合成的,因为它是由编译器“生成”以支持您正在做的事情):
pointcut anyMethodExecuted(): execution (* biz.ianw.lanchecker.*.*(..)) && !within(Trace) && !execution(synthetic * access$*(..));
或者您可以排除所有合成材料:
pointcut anyMethodExecuted(): execution (!synthetic * biz.ianw.lanchecker.*.*(..)) && !within(Trace);