AspectJ OR运算符似乎不起作用 [英] AspectJ OR Operator Doesn't Seem to be Functioning

查看:64
本文介绍了AspectJ OR运算符似乎不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用SpringAOP + AspectJ设置日志记录方面时遇到了一些麻烦.我想在使用@Loggable批注对类或方法进行批注时触发"Around"方法.下面是我的建议代码:

I'm having a little trouble getting a logging aspect set up using SpringAOP + AspectJ. I would like an "Around" method to fire when either a class or method is annotated with the @Loggable annotation. Below is my advice code:

@Around(value = "execution( * *(..)) && target(bean) && @annotation(loggable)", argnames "bean, loggable")
public void test1(ProceedingJoinPoint method, Object bean, Loggable loggable) { }

@Around(value = "execution( * *(..)) && target(bean) && @within(loggable)", argnames "bean, loggable")
public void test2(ProceedingJoinPoint method, Object bean, Loggable loggable) { }

@Around(value = "execution( * *(..)) && target(bean) && (@annotation(loggable) || @within(loggable))", argnames "bean, loggable")
public void test3(ProceedingJoinPoint method, Object bean, Loggable loggable) { }

test1和test2触发.test3没有,这是我真正想要的.对为什么会这样有任何想法吗?

test1 and test2 fire. test3 does not, and it's the one that I really want. Any thoughts on why this might be?

推荐答案

首先,切入点中存在语法错误.它不是小写的 argnames ,而是 argNames ,并且您在参数名称和值之间缺少 = .因此它必须是 argNames ="bean,loggable" .

First of all, there are syntax errors in your pointcuts. It is not lower-case argnames but argNames and you are missing an = in between parameter name and value. So it must be argNames = "bean, loggable".

第二,如果您的建议返回 void ,则它将仅匹配返回 void 的方法.更一般的情况是在建议中返回 Object 以真正匹配所有方法.

Secondly if your advice returns void it will only match methods returning void as well. The more general case is to return Object in the advice to really match all methods.

最后但并非最不重要的是,您应该看到警告,该警告解释了第三个切入点的问题.这显示在您的Eclipse IDE或AspectJ编译器的( ajc )日志输出中:

Last but not least, you should see a warning which explains the problem with the third pointcut. This is displayed in your Eclipse IDE or on the AspectJ compiler's (ajc) log output:

ambiguous binding of parameter(s) loggable across '||' in pointcut

这意味着您不能说将一个值或另一个值绑定到参数'loggable'".如果两个条件都匹配怎么办?应该分配哪一个?您有两个选择,假设您的标准班级名称为 de.scrum_master.app.Loggable :

This means that you cannot say "bind one value or the other to the parameter 'loggable'". What if both conditions match? Which one should be assigned? You have two options, assuming your fully-qualified class name is de.scrum_master.app.Loggable:

A)无需引用 @Loggable 批注:

A) No reference to @Loggable annotation needed:

这是简单的情况.如果 @Loggable 没有需要读取的任何参数,则无需将其绑定到参数.顺便说一句,如果您希望切入点也捕获静态方法,则不应绑定 target(),因为目标将是 null .也许在Spring-AOP中这是无关紧要的,因为它无论如何都只能与Spring Beans一起使用,但是在功能齐全的AspectJ中,它将有所作为,因为它更强大.

This is the simple case. If @Loggable does not have any parameters you need to read, it is not necessary to bind it to a parameter. BTW, if you want your pointcut to also capture static methods, you should not bind target() either because the target would be null. Maybe in Spring-AOP this is irrelevant because it only works with Spring Beans anyway, but in full-featured AspectJ it would make a difference because it is more powerful.

@Around(value = "execution(* *(..)) && (@annotation(de.scrum_master.app.Loggable) || @within(de.scrum_master.app.Loggable))")
public Object withoutLoggableReference(ProceedingJoinPoint thisJoinPoint) {
    Object bean = thisJoinPoint.getTarget();
    System.out.println(thisJoinPoint + " -> " + bean);
    return thisJoinPoint.proceed();
}

或者,等效地:

@Around(value = "execution(* (@de.scrum_master.app.Loggable *.*)(..)) || execution(@de.scrum_master.app.Loggable * *.*(..))")
public Object withoutLoggableReference(ProceedingJoinPoint thisJoinPoint) {
    Object bean = thisJoinPoint.getTarget();
    System.out.println(thisJoinPoint + " -> " + bean);
    return thisJoinPoint.proceed();
}

B)需要引用 @Loggable 批注:

B) Reference to @Loggable annotation needed:

如果要将注解绑定到参数,除了选择两个单独的切入点外,您别无选择.也许您可以使用实用程序方法进行实际记录,以避免建议中的代码重复.

You have no other choice than to go with two separate pointcuts if you want to bind the annotations to parameters. Maybe you could use a utility method doing the actual logging in order to avoid code duplication in your advice.

这篇关于AspectJ OR运算符似乎不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆