AspectJ - Est-il possible de prendre l'exécution d'un conseil?
Question
j'ai un CachingAspect
qui effectue une mise en cache simple sur des méthodes correctement annotées around
conseils. Maintenant, ce que je veux faire, c'est tracer la mise en cache et le around
conseils en particulier.
Jusqu'à présent, je suis capable d'intercepter les appels de méthode dans le around
conseils mais pas les conseils eux-mêmes. En fin de compte, je voudrais obtenir la signature de la méthode la around
Des conseils sont des conseils. Est-il possible?
Merci d'avance!
La solution
Que veux-tu dire par
AdviceExecution Pointcut] ne fonctionne pas pour moi
Pour moi, cela fonctionne très bien, comme ça:
public aspect MetaAspect {
before() : within(DummyAspect) && adviceexecution() {
System.out.println("MetaAspect: " + thisJoinPointStaticPart.getSignature());
for (Object arg : thisJoinPoint.getArgs())
System.out.println(" " + arg);
}
}
À partir de ce moment, en regardant les signatures imprimées, vous devriez être en mesure d'affiner les conseils à choisir parmi DummyAspect s'il y en a plusieurs et ils ont des signatures différentes.
Mise à jour:
D'accord, vous avez édité votre question et indiqué que ce que vous devez déterminer n'est pas seulement adviceexecution()
mais aussi la signature de la méthode interceptée. Il n'y a pas de solution à 100% pour cela, mais si vous vous assurez que vos conseils interceptés se réfèrent en quelque sorte aux méthodes de thisJoinPointStaticPart
, une instance de JoinPoint.StaticPart
sera ajouté à la propre signature du conseil et est accessible à partir de votre méta-aspect. Voici un exemple de code complet:
Application du conducteur:
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) {}
}
Aspect de mise en cache:
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);
}
}
Comme vous pouvez le voir, il y a deux conseils dans cet aspect. Le premier n'accède aucun membre de jointure, le second. C'est-à-dire que nous serons en mesure de découvrir la signature cible de la seconde uniquement dans notre méta-aspect.
Meta Aspect:
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");
}
}
Le conseil des méta itère sur ses paramètres afin de trouver un JoinPoint.StaticPart
Paramètre de type. S'il en trouve un, il imprime sa signature cible, sinon il imprime une note de défaillance après la boucle.
Exemple de sortie:
[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)
Autres conseils
Vous pouvez utiliser thisJoinpoint.getSignature () dans les conseils pour obtenir la signature de la méthode comme ceci:
pointcut tolog1() : execution(* Activity+.*(..)) ;
before() : tolog1() {
String method = thisJoinPoint.getSignature().toShortString();
Log.d(ATAG, "=========== entering " + method+", parms="+Arrays.toString(thisJoinPoint.getArgs()));
}