簡體   English   中英

AspectJ-在指定方法處的切入點,其參數帶有類級別的注釋

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM