[英]AspectJ - Pointcut at specified method with a param annotated with class level annotation
一方面,我想停止使用指定的方法。 此方法具有一個用類級別注釋注釋的參數:
注釋是:
@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
更新:為了在不更改或重載任何方法簽名的情況下使整個工作正常進行,您必須使切入點與所有調用匹配,並通過反射與方面一起動態確定類型及其注釋(不是很好,但可能) 。 如果您不了解這個想法,請隨時提出問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.