Spring AOP: Was ist der Unterschied zwischen JoinPoint und PointCut?

88

Ich lerne aspektorientierte Programmierkonzepte und Spring AOP. Ich verstehe den Unterschied zwischen einem Pointcut und einem Joinpoint nicht - beide scheinen für mich gleich zu sein. Bei einem Pointcut wenden Sie Ihren Rat an, und bei einem Joinpoint können wir unseren Rat anwenden. Was ist dann der Unterschied?

Ein Beispiel für einen Pointcut kann sein:

@Pointcut("execution(* * getName()")

Was kann ein Beispiel für einen Joinpoint sein?

Saurabh Patil
quelle

Antworten:

161

Joinpoint: Ein Joinpoint ist ein Kandidatenpunkt in der Programmausführung der Anwendung, an dem ein Aspekt eingefügt werden kann. Dieser Punkt kann eine aufgerufene Methode, eine ausgelöste Ausnahme oder sogar ein geändertes Feld sein. Dies sind die Punkte, an denen der Code Ihres Aspekts in den normalen Ablauf Ihrer Anwendung eingefügt werden kann, um neues Verhalten hinzuzufügen.

Hinweis: Dies ist ein Objekt, das API-Aufrufe für systemweite Belange enthält, die die Aktion darstellen, die an einem durch einen Punkt angegebenen Joinpoint ausgeführt werden soll.

Pointcut: Ein Pointcut definiert, an welchen Verbindungspunkten der zugehörige Hinweis angewendet werden soll. Ratschläge können an jedem Joinpoint angewendet werden, der vom AOP-Framework unterstützt wird. Natürlich möchten Sie nicht alle Ihre Aspekte an allen möglichen Joinpoints anwenden. Mit Pointcuts können Sie angeben, wo Ihr Rat angewendet werden soll. Oft geben Sie diese Pointcuts mit expliziten Klassen- und Methodennamen oder durch reguläre Ausdrücke an, die übereinstimmende Klassen- und Methodennamenmuster definieren. In einigen AOP-Frameworks können Sie dynamische Pointcuts erstellen, die bestimmen, ob Ratschläge basierend auf Laufzeitentscheidungen angewendet werden sollen, z. B. den Wert von Methodenparametern.

Das folgende Bild kann Ihnen helfen, Ratschläge, PointCut und Joinpoints zu verstehen. Geben Sie hier die Bildbeschreibung ein

Quelle

Erklärung mit Restaurant Analogie: Quelle von @Victor

Wenn Sie in ein Restaurant gehen, sehen Sie sich ein Menü an und sehen mehrere Optionen zur Auswahl. Sie können einen oder mehrere Menüpunkte bestellen. Aber bis Sie sie tatsächlich bestellen, sind sie nur "Gelegenheit zum Essen". Sobald Sie die Bestellung aufgegeben haben und der Kellner sie zu Ihrem Tisch bringt, ist es eine Mahlzeit.

Joinpoints sind Optionen im Menü und Pointcuts sind Elemente, die Sie auswählen.

Ein Joinpoint ist eine Gelegenheit innerhalb des Codes, einen Aspekt anzuwenden ... nur eine Gelegenheit. Sobald Sie diese Gelegenheit nutzen und einen oder mehrere Joinpoints auswählen und einen Aspekt auf sie anwenden, erhalten Sie einen Pointcut.

Quell- Wiki :

Ein Join-Punkt ist ein Punkt im Kontrollfluss eines Programms, an dem der Kontrollfluss über zwei verschiedene Pfade ankommen kann (IMO: Rufen Sie deshalb Joint auf).

Beratung beschreibt eine Klasse von Funktionen, die andere Funktionen modifizieren

Ein Pointcut ist eine Reihe von Verbindungspunkten.

Premraj
quelle
3
Dies sollte als richtige Antwort markiert werden. Um weitere Informationen hinzuzufügen, schauen Sie sich die Antwort von Cragi Walls an ... coderanch.com/t/485525/Spring/Difference-Joint-Point-Point-Cut .
Victor
2
Auf den Punkt gebracht: Ein Pointcut definiert, an welchen Verbindungspunkten Ratschläge angewendet werden sollen +1
Naman Gala
Nur zur Bestätigung, zum more Joinpoints and apply an aspect to them, you've got a Pointcut. Aspekt für sie oder zum Rat für sie?
Asif Mushtaq
@Premraj Also, nach Ihrer Analogie wird der Rat das Essen bestellen. Habe ich recht?
Vishwas Atrey
Die Restaurant-Analogie hat dazu beigetragen, die Verwirrung zwischen JoinPoints und Pointcuts zu beseitigen. Danke!
SM
30

Um den Unterschied zwischen einem Verbindungspunkt und einem Punktschnitt zu verstehen, stellen Sie sich Punktschnitte als Angabe der Webregeln und Verbindungspunkte als Situationen vor, die diese Regeln erfüllen.

Im folgenden Beispiel

  @Pointcut("execution(* * getName()")  

Pointcut definiert Regeln, die besagen, dass Ratschläge auf die getName () -Methode angewendet werden sollten, die in einer Klasse in einem beliebigen Paket vorhanden ist, und Joinpoints eine Liste aller in Klassen vorhandenen getName () -Methoden sind, damit Ratschläge auf diese Methoden angewendet werden können.

(Im Falle des Frühlings wird die Regel nur auf verwaltete Bohnen angewendet, und Ratschläge können nur auf öffentliche Methoden angewendet werden.)

Sujay Mumbaraddi
quelle
1
"Pointcut definiert Regeln, die besagen, dass Ratschläge auf die getName () -Methode angewendet werden sollten, die in einer Klasse in einem beliebigen Paket vorhanden ist, und Joinpoints eine Liste aller in Klassen vorhandenen getName () -Methoden sind, damit Ratschläge auf diese Methoden angewendet werden können." Es tut mir leid, aber das wird verwirrender. Können Sie mir bitte eine Analogie in einem realen Alltagsszenario geben?
Saurabh Patil
28

JoinPoints: Dies sind im Grunde genommen Stellen in der eigentlichen Geschäftslogik, an denen Sie verschiedene Funktionen einfügen möchten, die erforderlich sind, aber nicht Teil der eigentlichen Geschäftslogik sind. Einige Beispiele für JoinPints ​​sind: Methodenaufruf, normal zurückgegebene Methode, Auslösen einer Ausnahme, Instanziieren eines Objekts, Verweisen auf ein Objekt usw.

Pointcuts: Pointcuts sind so etwas wie reguläre Ausdrücke, mit denen Joinpoints identifiziert werden. Pontcuts werden mit "pointcut expression language" ausgedrückt. Pointcuts sind Punkte des Ausführungsflusses, an denen das Querschnittsthema angewendet werden muss. Es gibt einen Unterschied zwischen Joinpoint und Pointcut. Joinpoints sind allgemeiner und stellen jeden Kontrollfluss dar, bei dem wir ein Querschnittsthema einführen möchten, während Pointcuts solche Joinpoints identifizieren, bei denen wir ein Querschnittsthema einführen möchten.

Krishna
quelle
1
Joinpoint - Mögliche Orte, an denen der Hinweiscode angewendet / ausgeführt werden kann. Pointcut - tatsächlich ausgewählte Joinpoints für die Ausführung des Hinweises.
user104309
24

Laienerklärung für jemanden, der neu in den Konzepten AOP ist. Dies ist nicht erschöpfend, sollte aber beim Erfassen der Konzepte helfen. Wenn Sie bereits mit der Grundsprache vertraut sind, können Sie jetzt aufhören zu lesen.

Angenommen, Sie haben einen Mitarbeiter der normalen Klasse und möchten jedes Mal etwas tun, wenn diese Methoden aufgerufen werden.

class Employee{
    public String getName(int id){....}
    private int getID(String name){...}
}

Diese Methoden werden als JoinPoints bezeichnet . Wir brauchen eine Möglichkeit, diese Methoden zu identifizieren, damit das Framework die Methoden unter allen geladenen Klassen finden kann. Wir werden also einen regulären Ausdruck schreiben, der der Signatur dieser Methoden entspricht. Es gibt zwar mehr, wie Sie weiter unten sehen werden, aber dieser reguläre Ausdruck definiert Pointcut . z.B

* * mypackage.Employee.get*(*)

First * steht für den Modifikator public / private / protected / default. Das zweite * steht für den Rückgabetyp der Methode.

Aber dann müssen Sie noch zwei weitere Dinge erzählen:

  1. Wann sollte eine Aktion ausgeführt werden - z. B. vor / nach der Methodenausführung ODER in Ausnahmefällen
  2. Was soll es tun, wenn es übereinstimmt (vielleicht einfach eine Nachricht drucken) ?

Die Kombination dieser beiden wird als Beratung bezeichnet .

Wie Sie sich vorstellen können, müssten Sie eine Funktion schreiben, um # 2 ausführen zu können. So könnte es also für die Grundlagen aussehen.

Hinweis: Verwenden Sie aus Gründen der Übersichtlichkeit das Wort REGEX anstelle von * * mypackage.Employee.get*(*). In Wirklichkeit geht der vollständige Ausdruck in die Definition ein.

@Before("execution(REGEX)")
public void doBeforeLogging() {....}   <-- executed before the matching-method is called

@After("execution(REGEX)")
public void doAfterLogging() {....}  <-- executed after the matching-method is called

Sobald Sie anfangen, diese häufig zu verwenden, geben Sie möglicherweise viele @ After / @ Before / @ Around-Ratschläge an. Die wiederholten regulären Ausdrücke werden letztendlich dazu führen, dass die Dinge verwirrend und schwer zu pflegen sind. Was wir also tun, wir geben dem Ausdruck einfach einen Namen und verwenden ihn überall in der Aspect-Klasse.

@Pointcut("execution(REGEX)") <-- Note the introduction of Pointcut keyword
public void allGetterLogging(){} <-- This is usually empty

@Before("allGetterLogging")
public void doBeforeLogging() {....}

@After("allGetterLogging")
public void doAfterLogging() {....}

Übrigens möchten Sie diese ganze Logik auch in eine Klasse einschließen , die Aspect heißt, und Sie würden eine Klasse schreiben:

@Aspect
public class MyAwesomeAspect{....}

Damit all diese Dinge funktionieren, müssen Sie Spring anweisen, die Klassen zu analysieren, um die @ AOP-Schlüsselwörter zu lesen, zu verstehen und Maßnahmen zu ergreifen. Eine Möglichkeit, dies zu tun, besteht darin, Folgendes in der XML-Datei der Frühlingskonfiguration anzugeben:

<aop:aspectj-autoproxy>

Dev S.
quelle
1
Ich bin neu bei AOP und diese Erklärung hat mir geholfen, die Beziehung zwischen Ratschlägen / Pointcuts / JoinPoints ganz klar zu verstehen.
Jatin Shashoo
11

Wenn Sie eine AOP-Sprache wie AspectJ mit einer Datenabfragesprache wie SQL vergleichen, können Sie sich Joinpoints (dh alle Stellen in Ihrem Code, an denen Sie Aspektcode weben können) als Datenbanktabelle mit vielen Zeilen vorstellen. Ein Pointcut ist wie ein SELECT-Stamement, mit dem eine benutzerdefinierte Teilmenge von Zeilen / Joinpoints ausgewählt werden kann. Der tatsächliche Code, den Sie in diese ausgewählten Stellen einweben, wird als Beratung bezeichnet.

Kriegaex
quelle
9

Definitionen

Gemäß Dokumentation:

Verbindungspunkt: Ein Punkt während der Ausführung eines Programms, z. B. die Ausführung einer Methode oder die Behandlung einer Ausnahme.

Sie können Joint Points als Ereignisse bei der Ausführung eines Programms betrachten. Wenn Sie Spring AOP verwenden, ist dies sogar auf den Aufruf von Methoden beschränkt. AspectJ bietet mehr Flexibilität.

Aber Sie kümmern sich nie um alle Ereignisse, da Sie nicht alle Speisen auf der Speisekarte essen, wenn Sie in ein Restaurant gehen (ich kenne Sie vielleicht nicht! Aber ich weiß es bestimmt nicht). Sie treffen also eine Auswahl von Ereignissen, die behandelt werden sollen, und was mit ihnen zu tun ist. Hier geht Pointcuts . Gemäß der Dokumentation,

Pointcut : Ein Prädikat, das mit Verknüpfungspunkten übereinstimmt .

Dann verbinden Sie , was mit dem zu tun Pointcut , es geht Beratung . Gemäß der Dokumentation,

Der Hinweis ist einem Pointcut- Ausdruck zugeordnet und wird an jedem Verknüpfungspunkt ausgeführt, der mit dem Pointcut übereinstimmt.

Code

package com.amanu.example;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

/**
 * @author Amanuel Nega on 10/25/16.
 */
class ExampleBussinessClass {

    public Object doYourBusiness() {
        return new Object();
    }

}

@Aspect
class SomeAspect {

    @Pointcut("execution(* com.amanu.example.ExampleBussinessClass.doYourBusiness())")
    public void somePointCut() {
    }//Empty body suffices

    @After("somePointCut()")
    public void afterSomePointCut() {
        //Do what you want to do after the joint point is executed
    }

    @Before("execution(* *(*))")
    public void beforeSomePointCut() {
        //Do what you want to do before the joint point is executed
    }

}

Erklärung des Codes

  • ExampleBusinessClass Wenn Proxy-Ed, ist unser Ziel!
  • doYourBusiness()ist ein möglicher gemeinsamer Punkt
  • SomeAspect ist unser Aspekt, der in mehrere Anliegen wie Arsch übergeht ExampleBusinessClass
  • somePointCut()ist eine Definition eines Punktschnitts , der unserem gemeinsamen Punkt entspricht
  • afterSomePointCut()ist eine Beratung , die nach unserem ausgeführt wird somePointCut Punkt geschnitten , die übereinstimmt doYourBusiness() gemeinsamen Punkt
  • beforeSomePointCut()ist auch ein Ratschlag , der allen publicMethodenausführungen entspricht. Im Gegensatz afterSomePointCutdazu wird hier eine Inline-Punktschnittdeklaration verwendet

Sie können sich die Dokumentation ansehen, wenn Sie mir nicht glauben. ich hoffe das hilft

Amanuel Nega
quelle
1
Einfache Erklärung. Nur drei zitierte Texte reichen zum Verständnis aus. Vielen Dank.
TRiNE
6

Beide beziehen sich auf das "Wo" der aspektorientierten Programmierung.

Ein Join-Punkt ist ein einzelner Ort, an dem Sie Code mit AOP ausführen können. ZB "wenn eine Methode eine Ausnahme auslöst".

Ein Pointcut ist eine Sammlung von Verknüpfungspunkten. ZB "wenn eine Methode in der Klasse Foo eine Ausnahme auslöst".

Matthew Groves
quelle
4

JoinPoint : Joinpoint sind Punkte in Ihrer Programmausführung, an denen der Ausführungsfluss geändert wurde, z. B. Ausnahmefang, Aufrufen einer anderen Methode.

PointCut : PointCut sind im Grunde die Joinpoints, an denen Sie Ihre Ratschläge (oder Anrufaspekte) abgeben können.

PointCuts sind also im Grunde die Teilmenge von JoinPoints .

Vikas Bhardwaj
quelle
3

AOP im Frühjahr hat {Advisor, Advice, Pointcut, Joinpoint}

Wie Sie wissen, besteht der Hauptzweck von aop darin, die Querschnittslogik (Aspekt) vom Anwendungscode zu entkoppeln, um dies im Frühjahr zu implementieren, das wir verwenden (Beratung / Berater).

Pointcut wird verwendet, um zu filtern, wo wir diesen Hinweis genau anwenden möchten, z. B. "Alle Methoden beginnen mit Einfügen", sodass andere Methoden ausgeschlossen werden. Aus diesem Grund haben wir in der Pointcut-Schnittstelle {ClassFilter und MethodMatcher}

Beratung ist also die übergreifende Logikimplementierung und Advisor ist der Ratschlag plus der PointCut. Wenn Sie nur den Ratgeber verwenden, ordnet Spring ihn dem Berater zu und macht den Pointcut TRUE, was bedeutet, dass nichts blockiert wird. Wenn Sie nur Ratschläge verwenden, werden diese auf alle Methoden der Zielklasse angewendet, da Sie sie nicht gefiltert haben.

Joinpoint ist jedoch ein Speicherort im Programm. Wenn Sie auf das Class-Objekt zugreifen, können Sie es als Reflexion betrachten. Anschließend können Sie das Method-Objekt abrufen. Anschließend können Sie eine beliebige Methode in dieser Klasse aufrufen. So funktioniert der Compiler, wenn Sie möchten Dies können Sie sich den Joinpoint vorstellen.

Joinpoint kann mit Feld, Konstruktor oder Methode sein, aber im Frühjahr haben wir Joinpoint nur mit Methoden. Deshalb haben wir im Frühjahr Joinpoint-Typen (Vorher, Nachher, Wirf, Herum), die sich alle auf Positionen in der Klasse beziehen.

Wie ich bereits erwähnt habe, können Sie Ratschläge ohne Pointcut (ohne Filter) erhalten, die dann auf alle Methoden angewendet werden, oder Sie können einen Berater haben, der [Beratung + Pointcut] ist und auf bestimmte Methoden angewendet wird, ohne den Sie jedoch keine Ratschläge erhalten können Joinpoint wie Pointcut müssen Sie angeben, und deshalb sind Beratungstypen im Frühjahr genau die gleichen Typen wie der Joinpoint. Wenn Sie also einen Rat auswählen, wählen Sie implizit den Joinpoint aus.

Zum Abschluss ist die Beratung die Implementierungslogik für Ihren Aspekt für die Zielklasse. Diese Beratung sollte einen Verknüpfungspunkt wie vor dem Aufruf, nach dem Aufruf, nach dem Werfen oder um den Aufruf haben. Anschließend können Sie mithilfe von pointcut filtern, wo genau Sie ihn anwenden möchten Filtern Sie die Methoden oder keinen Pointcut (kein Filter), damit er auf alle Methoden der Klasse angewendet wird.

Ahmad
quelle
3

In der Implementierung der Aspect-Klasse wird ein Pointcut definiert. Der Punktschnitt bezieht sich im Wesentlichen auf den Punktschnittausdruck innerhalb des Hinweises.

Zum Beispiel

@Before("execution(* app.purchase2.service.impl.*(..))")
public void includeAddOns(RolesAllowed roles) {
..
}

Das obige bedeutet, dass die Methode "includeAddOns" aufgerufen wird, bevor (aufgrund der @ Vorher-Empfehlung) Methoden aufgerufen werden (in Klassen innerhalb des Pakets "app.purchase2.service.impl").

Die gesamte Anmerkung wird als Pointcut bezeichnet @Before("execution(* app.purchase2.service.impl.*(..))")

Gemeinsamer Punkt ist der eigentliche Methodenaufruf, der die Methode im Paket "app.purchase2.service.impl" mit der Methode in der Aspektklasse "includeAddOns ()" verknüpft hat.

Sie können mit der org.aspectj.lang.JoinPointKlasse auf Eigenschaften des Verknüpfungspunkts zugreifen .

Überprüfen Sie dies
quelle
Gute Antwort! Endlich habe ich den Unterschied verstanden!
Dante
2

Ich stimme mgroves zu. Ein Punktschnitt kann als Sammlung mehrerer Gelenkpunkte betrachtet werden. Gemeinsamer Punkt Geben Sie den bestimmten Ort an, an dem der Rat umgesetzt werden könnte, wobei der Punktschnitt die Liste aller gemeinsamen Punkte widerspiegelt.

Yonikawa
quelle
0

JoinPoint: Gibt einen Punkt (eine Methode) in der Anwendung an, an dem Advice ausgeführt wird.

Pointcut: Dies ist eine Kombination von JoinPoints und gibt an, bei welcher JoinPoint-Beratung ausgeführt wird.

Akash5288
quelle
-5

Der Verbindungspunkt ist ein Ort, an dem wir die Ratschläge tatsächlich platzieren

Der Punktschnitt ist jedoch die Sammlung von Verbindungspunkten. Das heißt, auf wie viele Arten wir die Querschnittslogik platzieren, wird als Punktschnitt bezeichnet

user4327697
quelle