So che questo è un vecchio post ma ho appena trovato un'importante differenza tra questo e il target mentre non utilizzo AspectJ.
Si consideri il seguente aspetto introduzione:
@Aspect
public class IntroductionsAspect {
@DeclareParents(value="a.b.c.D", defaultImpl=XImpl.class)
public static X x;
@After("execution(* a.b.c.D.*(..)) && this(traceable)")
public void x(Traceable traceable) {
traceable.increment();
}
}
In poche parole, questo aspetto sta facendo due cose:
- Rendere la classe
a.b.c.D
implementare l'interfaccia X
.
- aggiungere una chiamata a
traceable.increment()
che deve essere eseguito prima di ogni metodo di a.b.c.D
.
La parte importante è "execution(* a.b.c.D.*(..)) && this(traceable)"
. Si noti che ho utilizzato questo, non target.
Se si utilizza bersaglio invece, si sta cercando di abbinare la classe originale a.b.c.D
, non l'interfaccia introdotta X
. Quindi Spring AOP non troverà alcun punto di unione in a.b.c.D
.
In sintesi:
questo - controlla il tipo di proxy, o il tipo introdotto. target - Controlla il tipo dichiarato.
Se ottengo il tasto destro ... sia '' this' e target' fanno la stessa cosa ??? Una volta che il mio codice tenta di eseguire un metodo di 'AccountService', quindi dal punto di vista del ricevitore,' questa istanza di AccountService' è vera; e dal punto di vista del chiamante 'calledObject instanceof AccountService' è anche vero. Allora, perché questa ridondanza? – rapt
È importante in AspectJ ma hai ragione non tanto in Spring AOP - perché 'call' (tipicamente usato con target) intaccherà il chiamante, mentre' execution' (insieme a questo) tesserà la classe stessa. Questo è importante poiché con qualcosa come la tessitura in tempo di compilazione potresti non avere accesso a classi terze per tessere usando l'esecuzione, puoi quindi intrecciare le chiamate alle librerie di terze parti. –
Grazie per la spiegazione. – rapt