簡體   English   中英

使用Aspectj截取具有反射的任務

[英]Using aspectj to intercept an assignment with reflection

當我使用tomcat運行應用程序時,它說建議沒有被應用,因此我的方面將無法正常工作。 我必須在任何地方進行配置嗎? 我沒有做任何事情,所以我不知道什么代碼可能有用。

謝謝!

編輯

我剛剛找到了解決方法,即使它說尚未應用該方面,當我調用setter時,它也可以工作,但是在使用反射時卻遇到了問題。

我有一個方面可以攔截一個有效的字段的setter,但是當從Gson庫por示例分配值時,它不起作用。

這是方面:

public aspect AnnotationAspect {

    pointcut hasAnnotation(Annotation annotation) : @annotation(annotation);

    Object around(Annotation annotation, String word) : hasAnnotation(annotation) && set(String *) && args(word) {
        Object result = null;
        try {
            result = proceed(annotation, "intercepted");
        } catch (RuntimeException ex) {
            throw ex;
        }
        return result;
    }
}

我有這個課:

public class JavaEntity {

    @Annotation
    public String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

當我做這樣的事情時,它不會攔截作業:

JavaEntity entity = new Gson().fromJson("{\"name\":\"name\"}", JavaEntity.class);

反正有攔截嗎? 謝謝!

反射場訪問不能被AspectJ直接攔截。 您只能通過用火撲滅它來解決它,即也可以使用反射:

  • 確保Gson位於AspectJ編譯器的inpath中(即,對AspectJ Maven插件的編織依賴項),以便能夠編織到其代碼中。
  • 攔截對Field.set(..)調用。
  • 在攔截建議檢查中,要設置哪個字段,通過反射查找其注釋,以模擬@annotation(blah) ,決定是否修改其值。

這不是完全的AspectJ用例,而是可能的。

順便說一句,您對execution()連接點沒有這種問題,因為它們在反射性調用方法時也會被觸發。 但是,您會遇到call()問題。 但這僅是供您參考,與該特定情況沒有直接關系。


更新:我的意思是這樣的:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <configuration>
        <weaveDependencies>
            <weaveDependency>
                <groupId>Group</groupId>
                <artifactId>model</artifactId>
            </weaveDependency>
            <weaveDependency>
                <groupId>com.google.code.gson</groupId>
                <artifactId>gson</artifactId>
            </weaveDependency>
        </weaveDependencies>
    </configuration>
</plugin>
@Test
public void testingInterceptWithJavaGson(){
    javaEntity = new Gson().fromJson("{\"name\":\"newName\"}", JavaEntity.class);
    Assert.assertEquals("intercepted", javaEntity.getName());
}
Object around(Field field, Object obj, Object value) :
    within(com.google.gson..*) &&
    call(public void Field.set(Object, Object)) &&
    target(field) &&
    args(obj, value)
{
    Object result = null;
    System.out.println(thisJoinPoint);
    System.out.println("  " + field + " -> " + field.getAnnotation(Annotation.class));
    System.out.println("  " + obj);
    System.out.println("  " + value);
    try {
        if (field.getAnnotation(Annotation.class) != null && field.getType() == String.class)
            result = proceed(field, obj, "intercepted");
        else
            result = proceed(field, obj, value);
    } catch (RuntimeException ex) {
        throw ex;
    }
    return result;
}

實際上,您不需要通過args()綁定第一個參數obj ,我僅將其用於日志記錄即可向您顯示發生了什么。 因此,這種稍微簡單的形式也可以:

Object around(Field field, Object value) :
    within(com.google.gson..*) &&
    call(public void Field.set(Object, Object)) &&
    target(field) &&
    args(*, value)
{
    Object result = null;
    System.out.println(thisJoinPoint);
    try {
        if (field.getAnnotation(Annotation.class) != null && field.getType() == String.class)
            result = proceed(field, "intercepted");
        else
            result = proceed(field, value);
    } catch (RuntimeException ex) {
        throw ex;
    }
    return result;
}

對您現有GitHub存儲庫的更改包含在我的fork中的另一個pull請求中

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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