AspectJ - Можно ли поймать исполнение совета? - PullRequest
1 голос
/ 18 мая 2011

У меня есть CachingAspect, который выполняет простое кэширование для правильно аннотированных методов, используя совет around.Теперь я хочу отследить кэширование и, в частности, around рекомендацию.

До сих пор я мог перехватывать вызовы методов внутри рекомендации around, но не сам совет.В конечном счете, я хотел бы получить подпись метода, который советует around.Возможно ли это?

Заранее спасибо!

Ответы [ 3 ]

1 голос
/ 19 мая 2011

Вы можете использовать thisJoinPoint.getSignature () внутри рекомендации, чтобы получить подпись метода следующим образом:

pointcut tolog1() : execution(* Activity+.*(..)) ;
before() : tolog1() {
    String method = thisJoinPoint.getSignature().toShortString();

    Log.d(ATAG, "=========== entering " + method+", parms="+Arrays.toString(thisJoinPoint.getArgs()));
}
1 голос
/ 09 августа 2012

Что вы подразумеваете под

[pointexecution pointcut] у меня не работает

Для меня это работает просто отлично, вот так:

public aspect MetaAspect {
    before() : within(DummyAspect) && adviceexecution() {
        System.out.println("MetaAspect: " + thisJoinPointStaticPart.getSignature());
        for (Object arg : thisJoinPoint.getArgs())
            System.out.println("    " + arg);
    }
}

С этого момента, глядя на напечатанные подписи, вы сможете уточнить, какой совет выбрать из DummyAspect, если их несколько, и у них разные подписи.


Обновление:

Хорошо, вы отредактировали свой вопрос и заявили, что вам нужно определить не только adviceexecution(), но и подпись перехваченного метода. Для этого не существует 100% -ного решения, но если вы убедитесь, что ваш перехваченный совет как-то ссылается на методы thisJoinPointStaticPart, экземпляр JoinPoint.StaticPart будет добавлен к собственной подписи совета и доступен из вашего мета-аспекта. Вот полный пример кода:

Приложение драйвера:

package de.scrum_master.app;

public class Application {
    public static void main(String[] args) {
        Application application = new Application();
        application.writeProperty("fullName", "John Doe");
        application.readProperty("firstName");
        application.doSomething(11);
    }

    public void writeProperty(String name, String value) {}
    public String readProperty(String name) { return "foo"; }
    public void doSomething(int number) {}
}

Кэширование:

package de.scrum_master.aspect;

public aspect CachingAspect {
    pointcut readMethods(String propertyName) :
        execution(* *.read*(String)) && args(propertyName);

    before(String propertyName) : readMethods(propertyName) {
        System.out.println(
            "[CachingAspect] Read method called for property '" + propertyName + "'"
        );
    }

    Object around(String propertyName) : readMethods(propertyName) {
        System.out.println(
            "[CachingAspect] Caching property '" + propertyName +
            "' in method " + thisJoinPointStaticPart.getSignature()
        );
        return proceed(propertyName);
    }
}

Как видите, в этом аспекте есть два совета. Первый не имеет доступа ни к каким членам точки присоединения, второй - к ним. То есть мы сможем узнать целевую сигнатуру второго только в нашем мета-аспекте.

Мета-аспект:

package de.scrum_master.aspect;

import org.aspectj.lang.JoinPoint.StaticPart;

public aspect AdviceInterceptor {
    before() : within(CachingAspect) && adviceexecution() {
        System.out.println("[AdviceInterceptor] Intercepting " + thisJoinPointStaticPart);
        boolean foundSignature = false;
        for (Object arg : thisJoinPoint.getArgs()) {
            if (arg instanceof StaticPart) {
                foundSignature = true;
                StaticPart jpStaticPart = (StaticPart) arg;
                System.out.println("[AdviceInterceptor] Target method = " + jpStaticPart.getSignature());
                break;
            }
        }
        if (!foundSignature)
            System.out.println("[AdviceInterceptor] Target method cannot be determined from advice signature");
    }
}

Мета-совет перебирает свои параметры, чтобы найти параметр типа JoinPoint.StaticPart. Если он находит его, он печатает свою целевую подпись, в противном случае он печатает примечание об ошибке после цикла.

Пример вывода:

[AdviceInterceptor] Intercepting adviceexecution(void de.scrum_master.aspect.CachingAspect.before(String))
[AdviceInterceptor] Target method cannot be determined from advice signature
[CachingAspect] Read method called for property 'firstName'
[AdviceInterceptor] Intercepting adviceexecution(Object de.scrum_master.aspect.CachingAspect.around(String, AroundClosure, JoinPoint.StaticPart))
[AdviceInterceptor] Target method = String de.scrum_master.app.Application.readProperty(String)
[CachingAspect] Caching property 'firstName' in method String de.scrum_master.app.Application.readProperty(String)
1 голос
/ 18 мая 2011
...