2012-08-12 8 views
10

Von Spring Documentation:Frühling AOP Ziel() vs diesem()

  • jeden Punkt join (Methodenausführung nur in Spring AOP), wo der Proxy den Account-Schnittstelle implementiert:

    this(com.xyz.service.AccountService) 
    
  • Jeder Join-Punkt (Methodenausführung nur im Spring-AOP), bei dem das Zielobjekt die AccountService-Schnittstelle implementiert:

    target(com.xyz.service.AccountService) 
    

Ich verstehe nicht, was "Zielobjekt" und der Ausdruck target(...) bedeuten.

Wie unterscheidet sich target von this?

Antwort

17

this(AType) bedeutet alle Join-Punkte, bei denen this instanceof AType wahr ist. Das bedeutet, dass in Ihrem Fall, sobald der Anruf eine Methode von AccountService erreicht, this instanceof AccountService wahr ist.

target(AType) bedeutet alle Join-Punkte, wo anObject instanceof AType. Wenn Sie eine Methode für ein Objekt aufrufen und dieses Objekt eine Instanz von AccountService ist, ist dies ein gültiger Joinpoint.

Um einen anderen Weg zusammenzufassen - this(AType) ist aus der Sicht eines Empfängers, und target(AType) ist aus Sicht eines Anrufers.

+0

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

+0

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. –

+0

Danke für die Erklärung. – rapt

9

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:

  1. machen die a.b.c.D Klasse die X-Schnittstelle implementieren.
  2. 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.

+0

guten Punkt, danke –

Verwandte Themen