在一方面,我想停止在指定的方法上。该方法有一个参数,该参数使用类级别注释进行注释:
注释是:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Auditable {}
参数是一个类的对象,注释如下:
@Auditable
public class User {}
我喜欢检查的方法:
public Object findSingleResultByExample(final Object entity) {}
这方面不起作用:
@AfterReturning(value="execution(* org.wtp.repository.GenericDao.find*(@org.wtp.aspects.Auditable (*)))",
argNames = "joinPoint, result",
returning = "result")
private void auditFindAnnotation(final JoinPoint joinPoint, final Object result) {}
最佳答案
首先,您的建议方法必须是public
,而不是private
。请将其更改为
public void auditFindAnnotation(...)
它不起作用,因为您的切入点拦截带有 @Auditable
参数注释的方法。不过,您的示例方法没有这样的注释。如果方法签名是这样的,那就可以了:
public Object findSingleResultByExample(final @Auditable Object entity) {}
顺便说一句,那么必须删除或扩展 @Target(ElementType.TYPE)
限制才能使代码仍然可以编译。
但我猜你想要的不是匹配参数注释,而是匹配类型注释。那么你的切入点将如下所示(这次 *
周围没有括号):
execution(* org.wtp.repository.GenericDao.find*(@org.wtp.aspects.Auditable *))
但是,这与您的示例方法不匹配,因为它的参数类型不是 User
或 Auditable
而只是 Object
并且后者确实不携带注释。如果您重载 find*
方法并执行以下操作,您可以看到差异:
package de.scrum_master.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Auditable {}
package de.scrum_master.app;
@Auditable
public class User {}
package de.scrum_master.app;
import java.util.ArrayList;
public class Application {
public Object findSingleResultByExample(final Object entity) {
return entity;
}
public Object findSingleResultByExample(final User entity) {
return entity;
}
public static void main(String[] args) {
Application application = new Application();
application.findSingleResultByExample("foo");
application.findSingleResultByExample(new User());
application.findSingleResultByExample(new ArrayList<String>());
}
}
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class AuditAspect {
@AfterReturning(
value = "execution(* de.scrum_master.app..find*(@de.scrum_master.app.Auditable *))",
argNames = "thisJoinPoint, result",
returning = "result"
)
public void auditFindAnnotation(final JoinPoint thisJoinPoint, final Object result) {
System.out.println(thisJoinPoint + " -> " + result);
}
}
控制台日志如下所示:
execution(Object de.scrum_master.app.Application.findSingleResultByExample(User)) -> de.scrum_master.app.User@4a574795
更新:为了让整个事情正常工作而不更改或重载任何方法签名,您必须使切入点匹配所有调用,并从方面动态确定类型及其注释通过反射(不太好,但可能)。如果您不明白这个想法,请随时提问。
关于java - AspectJ - 指定方法的切入点,其参数用类级别注释进行注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31073198/