Ich weiß, dass dies ein alter Beitrag ist, aber ich bin gerade auf einen wichtigen Unterschied zwischen diesem und dem Ziel gestoßen, ohne AspectJ zu verwenden.
Betrachten Sie die folgende Einführung Aspekt:
@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();
}
}
Einfach ausgedrückt, ist dieser Aspekt zwei Dinge tut:
- machen die
a.b.c.D
Klasse die X
-Schnittstelle implementieren.
- Hinzufügen eines Anrufs zu
traceable.increment()
, der vor jeder Methode von a.b.c.D
ausgeführt wird.
Der wichtige Teil ist "execution(* a.b.c.D.*(..)) && this(traceable)"
. Beachten Sie, dass ich dieses, nicht Ziel verwendet habe.
Wenn Sie Ziel verwenden stattdessen versuchen Sie a.b.c.D
die ursprüngliche Klasse entsprechen, nicht die eingeführte Schnittstelle X
. So findet Spring AOP keinen gemeinsamen Punkt in a.b.c.D
.
Zusammengefasst:
diese - Prüft den Proxy-Typ oder eingeführt Art. Ziel - Prüft den deklarierten Typ.
Wenn ich Sie recht verstehe ... beide 'this' und' target' das gleiche tun ??? Sobald mein Code versucht, eine Methode von "AccountService" auszuführen, ist aus Sicht des Empfängers "diese Instanz von AccountService" wahr; und aus Sicht des Aufrufers 'calledObject instanceof AccountService' ist auch wahr. Warum also diese Redundanz? – rapt
Es spielt in AspectJ eine Rolle, aber Sie haben recht wenig im Spring AOP - weil 'call' (typischerweise mit Ziel verwendet) den Aufrufer weben wird, während' execution' (zusammen mit diesem) die Klasse selbst weben wird. Dies ist wichtig, da mit etwas wie Kompilierzeit Weben Sie möglicherweise keinen Zugriff auf Drittanbieter-Klasse haben, um mit Ausführung zu weben, können Sie dann die Aufrufe zu den Third-Party-Bibliotheken weben. –
Danke für die Erklärung. – rapt