Spring AOP: qual è la differenza tra JoinPoint e PointCut?


88

Sto imparando i concetti di programmazione orientata agli aspetti e Spring AOP. Non riesco a capire la differenza tra un Pointcut e un Joinpoint: entrambi sembrano essere uguali per me. Un Pointcut è dove applichi i tuoi consigli e un Joinpoint è anche un luogo in cui possiamo applicare i nostri consigli. Allora qual è la differenza?

Un esempio di taglio a punti può essere:

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

Quale può essere un esempio di Joinpoint?

Risposte:


161

Joinpoint: un joinpoint è un punto candidato nell'esecuzione del programma dell'applicazione in cui è possibile collegare un aspetto. Questo punto potrebbe essere un metodo chiamato, un'eccezione generata o anche un campo modificato. Questi sono i punti in cui il codice del tuo aspetto può essere inserito nel normale flusso della tua applicazione per aggiungere un nuovo comportamento.

Consiglio: questo è un oggetto che include invocazioni API alle preoccupazioni dell'intero sistema che rappresentano l'azione da eseguire in un punto di unione specificato da un punto.

Pointcut: un pointcut definisce a quali punti di unione deve essere applicato il Consiglio associato. I consigli possono essere applicati a qualsiasi punto di unione supportato dal framework AOP. Ovviamente, non vuoi applicare tutti i tuoi aspetti a tutti i possibili punti di unione. Le scorciatoie ti consentono di specificare dove desideri applicare il tuo consiglio. Spesso si specificano queste scorciatoie utilizzando nomi di classi e metodi espliciti o tramite espressioni regolari che definiscono modelli di nomi di classi e metodi corrispondenti. Alcuni framework AOP consentono di creare pointcut dinamici che determinano se applicare consigli basati su decisioni di runtime, come il valore dei parametri del metodo.

L'immagine seguente può aiutarti a comprendere Advice, PointCut, Joinpoints. inserisci qui la descrizione dell'immagine

fonte

Spiegazione usando Restaurant Analogy: Fonte di @Victor

Quando esci in un ristorante, guardi un menu e vedi diverse opzioni tra cui scegliere. Puoi ordinare uno o più degli elementi del menu. Ma fino a quando non li ordinate, sono solo "opportunità per cenare". Una volta che effettui l'ordine e il cameriere lo porta al tuo tavolo, è un pasto.

I punti di unione sono opzioni nel menu e i collegamenti di puntamento sono elementi selezionati.

Un Joinpoint è un'opportunità all'interno del codice per applicare un aspetto ... solo un'opportunità. Una volta che cogli questa opportunità e selezioni uno o più Joinpoint e applichi un aspetto ad essi, hai un Pointcut.

Wiki di origine :

Un punto di unione è un punto nel flusso di controllo di un programma in cui il flusso di controllo può arrivare attraverso due percorsi diversi (IMO: ecco perché chiamare giunto).

Il consiglio descrive una classe di funzioni che modificano altre funzioni

Un pointcut è un insieme di punti di unione.


3
Questo dovrebbe essere contrassegnato come risposta corretta. Solo per aggiungere qualche informazione in più, guarda la risposta di Cragi Walls ... coderanch.com/t/485525/Spring/Difference-Joint-Point-Point-Cut .
Victor

2
Al punto: un taglio di punti definisce a quale consiglio di joinpoint dovrebbe essere applicato +1
Naman Gala

Solo per conferma, more Joinpoints and apply an aspect to them, you've got a Pointcut. aspetto a loro o consiglio a loro?
Asif Mushtaq

@Premraj Quindi, secondo il tuo consiglio di analogia, ordinerò il pasto. Ho ragione?
Vishwas Atrey

L'analogia con il ristorante ha contribuito a chiarire la confusione tra JoinPoint e pointcuts, grazie!
SM

30

Per capire la differenza tra un punto di unione e un taglio di punti, pensa ai tagli di punti come a specificare le regole di tessitura e ai punti di unione come situazioni che soddisfano quelle regole.

Nell'esempio seguente,

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

Pointcut definisce le regole dicendo che il consiglio dovrebbe essere applicato sul metodo getName () presente in qualsiasi classe in qualsiasi pacchetto e joinpoints sarà un elenco di tutti i metodi getName () presenti nelle classi in modo che il consiglio possa essere applicato su questi metodi.

(In caso di primavera, la regola verrà applicata solo ai bean gestiti e i consigli possono essere applicati solo ai metodi pubblici).


1
"Pointcut definisce le regole dicendo che il consiglio dovrebbe essere applicato sul metodo getName () presente in qualsiasi classe in qualsiasi pacchetto e joinpoints sarà un elenco di tutti i metodi getName () presenti nelle classi in modo che il consiglio possa essere applicato su questi metodi." Mi dispiace ma la cosa sta diventando sempre più confusa. Puoi darmi un'analogia in uno scenario di vita quotidiana nel mondo reale?
Saurabh Patil

28

JoinPoint: si tratta fondamentalmente di luoghi nella logica aziendale effettiva in cui si desidera inserire alcune funzionalità varie che sono necessarie ma non fanno parte della logica aziendale effettiva. Alcuni esempi di JoinPints ​​sono: chiamata al metodo, metodo che restituisce normalmente, metodo che lancia un'eccezione, istanziazione di un oggetto, riferimento a un oggetto, ecc ...

Pointcuts: i pointcuts sono qualcosa come espressioni regolari utilizzate per identificare i punti di unione. I collegamenti sono espressi utilizzando il "linguaggio di espressione pointcut". I pointcuts sono punti del flusso di esecuzione in cui è necessario applicare la preoccupazione trasversale. C'è una differenza tra Joinpoint e Pointcut; I joinpoint sono più generali e rappresentano qualsiasi flusso di controllo in cui "possiamo scegliere" di introdurre una preoccupazione trasversale, mentre i pointcuts identifica tali punti di unione in cui "vogliamo" introdurre una preoccupazione trasversale.


1
Joinpoint: potenziali luoghi per applicare / eseguire il codice di consulenza. Pointcut - punti di unione scelti effettivi per l'esecuzione del consiglio.
user104309

24

Spiegazione laica per qualcuno che è nuovo ai concetti AOP. Questo non è esaustivo, ma dovrebbe aiutare a cogliere i concetti. Se hai già familiarità con il gergo di base, puoi smettere di leggere ora.

Supponiamo di avere una normale classe Employee e di voler fare qualcosa ogni volta che vengono chiamati questi metodi.

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

questi metodi sono chiamati JoinPoints . Abbiamo bisogno di un modo per identificare questi metodi in modo che il framework possa trovare i metodi, tra tutte le classi.metodi che ha caricato. Quindi scriveremo un'espressione regolare per abbinare la firma di questi metodi. Anche se c'è di più come vedrai di seguito, ma vagamente questa espressione regolare è ciò che definisce Pointcut . per esempio

* * mypackage.Employee.get*(*)

Il primo * è per il modificatore public / private / protected / default. Il secondo * è per il tipo restituito del metodo.

Ma poi devi anche dire altre due cose:

  1. Quando deve essere intrapresa un'azione, ad esempio prima / dopo l'esecuzione del metodo O in caso di eccezione
  2. Cosa dovrebbe fare quando corrisponde (forse basta stampare un messaggio)

La combinazione di questi due si chiama Consigli .

Come puoi immaginare, dovresti scrivere una funzione per poter fare # 2. Quindi questo è come potrebbe apparire per le basi.

Nota: per maggiore chiarezza, utilizzare la parola REGEX invece di * * mypackage.Employee.get*(*). In realtà la piena espressione va nella definizione.

@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

Una volta che inizi a usarli un po ', potresti finire per specificare molti consigli @ After / @ Before / @ Around. Le ripetute espressioni regolari finiranno per rendere le cose confuse e difficili da mantenere. Quindi quello che facciamo, diamo solo un nome all'espressione e lo usiamo ovunque nella classe Aspect.

@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() {....}

A proposito, vorresti anche racchiudere l'intera logica in una classe, che si chiama Aspect e scriveresti una classe:

@Aspect
public class MyAwesomeAspect{....}

Per far funzionare tutte queste cose, dovresti dire a Spring di analizzare le classi per leggere, comprendere e agire sulle parole chiave @ AOP. Un modo per farlo è specificare quanto segue nel file xml di configurazione di primavera:

<aop:aspectj-autoproxy>


1
Sono nuovo in AOP e questa spiegazione mi ha aiutato a capire abbastanza chiaramente la relazione tra Consigli / Pointcuts / JoinPoints.
Jatin Shashoo

11

Confrontando un linguaggio AOP come AspectJ con un linguaggio di query di dati come SQL, puoi pensare ai punti di unione (cioè tutti i punti nel tuo codice in cui puoi tessere il codice di aspetto) come una tabella di database con molte righe. Un pointcut è come uno stamement SELECT che può selezionare un sottoinsieme definito dall'utente di righe / punti di unione. Il codice effettivo che inserisci in quei luoghi selezionati si chiama consiglio.


9

Definizioni

Come da documentazione:

Punto di unione: un punto durante l'esecuzione di un programma, come l'esecuzione di un metodo o la gestione di un'eccezione.

Puoi considerare i punti congiunti come eventi in esecuzione di un programma. Se stai usando Spring AOP, questo è anche limitato all'invocazione di metodi. AspectJ offre maggiore flessibilità.

Ma non gestisci mai tutti gli eventi perché non mangi tutto il cibo nel menu quando vai in un ristorante (non ti conosco, potresti! Ma io di certo no). Quindi fai una selezione di eventi da gestire e cosa farne. Ecco Pointcuts . Come da documentazione,

Pointcut : un predicato che corrisponde ai punti di unione .

Quindi associ cosa fare con Pointcut , ecco i Consigli . Come da documentazione,

Il consiglio è associato a un'espressione pointcut e viene eseguito in qualsiasi punto di join corrispondente al pointcut.

Codice

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
    }

}

Spiegazione del codice

  • ExampleBusinessClass quando viene eseguito tramite proxy, è il nostro obiettivo!
  • doYourBusiness()è un possibile punto di giunzione
  • SomeAspect è il nostro aspetto che attraversa molteplici preoccupazioni come il culo ExampleBusinessClass
  • somePointCut()è una definizione di un punto di taglio che corrisponde al nostro punto comune
  • afterSomePointCut()è un consiglio che verrà eseguito dopo il nostro somePointCut taglio del punto che corrisponde al doYourBusiness() punto comune
  • beforeSomePointCut()è anche un consiglio che corrisponde a tutte le publicesecuzioni dei metodi. Diversamente afterSomePointCut, questo utilizza una dichiarazione di taglio del punto in linea

Puoi guardare la documentazione se non mi credi. Spero che aiuti


1
Semplice spiegazione. Solo tre testi citati sono sufficienti per capire. Grazie.
TRiNE

6

Entrambi riguardano il "dove" della programmazione orientata agli aspetti.

Un punto di unione è una singola posizione in cui è possibile eseguire codice con AOP. Ad esempio "quando un metodo genera un'eccezione".

Un pointcut è una raccolta di punti di unione. Ad esempio "quando un metodo nella classe Foo genera un'eccezione".


4

JoinPoint : Joinpoint sono punti nell'esecuzione del programma in cui il flusso di esecuzione è stato modificato come il rilevamento delle eccezioni, la chiamata di un altro metodo.

PointCut : I PointCut sono fondamentalmente quei Joinpoint in cui puoi mettere i tuoi consigli (o chiamare aspetto).

Quindi fondamentalmente PointCuts sono il sottoinsieme di JoinPoints .


3

AOP in primavera ha {Advisor, Advice, Pointcut, Joinpoint}

Come sapete lo scopo principale di aop è disaccoppiare la logica della preoccupazione trasversale (Aspect) dal codice dell'applicazione, per implementarla in primavera usiamo (Advice / Advisor)

Pointcut viene utilizzato per filtrare dove vogliamo applicare esattamente questo consiglio, come "tutti i metodi iniziano con insert" quindi altri metodi saranno esclusi ecco perché abbiamo nell'interfaccia Pointcut {ClassFilter e MethodMatcher}

Quindi Advice è l'implementazione logica trasversale e Advisor è il consiglio più PointCut, se si utilizza solo il consiglio Spring lo mapperà su advisor e renderà il pointcut TRUE, il che significa non bloccare nulla. Ecco perché quando usi solo i consigli viene applicato a tutti i metodi della classe target perché non li hai filtrati.

Ma Joinpoint è una posizione nel programma, puoi pensarla come una riflessione quando accedi all'oggetto Class e quindi puoi ottenere l'oggetto Method, quindi puoi invocare qualsiasi metodo in questa classe, ed è così che funziona il compilatore, se pensi come questo puoi immaginare il Joinpoint.

Joinpoint può essere con campo, costruttore o metodo, ma in Spring abbiamo joinpoint solo con metodi, ecco perché in Spring abbiamo tipi di Joinpoint (Before, After, Throws, Around), tutti si riferiscono a posizioni nella classe.

Come ho già detto puoi avere consigli senza pointcut (nessun filtro), quindi sarà applicato a tutti i metodi oppure puoi avere un advisor che è [consiglio + pointcut] che verrà applicato a metodi specifici ma non puoi avere consigli senza joinpoint come pointcut, devi specificarlo, ed è per questo che i tipi di consigli in primavera sono esattamente gli stessi tipi del joinpoint, quindi quando scegli un consiglio scegli implicitamente quale joinpoint.

Per concludere, il consiglio è la logica di implementazione per il tuo aspetto alla classe di destinazione, questo consiglio dovrebbe avere un punto di unione come prima dell'invocazione, dopo l'invocazione, dopo il lancio o intorno all'invocazione, quindi puoi filtrare esattamente dove vuoi applicarlo usando pointcut a filtra i metodi o nessun taglio di punti (nessun filtro) in modo che venga applicato a tutti i metodi della classe.


3

Un taglio di punti è definito nell'implementazione della classe Aspect. Il taglio del punto si riferisce fondamentalmente all'espressione del taglio del punto all'interno del consiglio.

Ad esempio,

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

Quanto sopra significa che il metodo "includeAddOns" viene chiamato prima di invocare (a causa del consiglio @Before) qualsiasi metodo (nelle classi all'interno del pacchetto "app.purchase2.service.impl")

L'intera annotazione è chiamata pointcut @Before("execution(* app.purchase2.service.impl.*(..))")

Il punto comune è l'attuale invocazione del metodo, che ha unito il metodo nel pacchetto "app.purchase2.service.impl" al metodo nella classe di aspetto "includeAddOns ()".

È possibile accedere alle proprietà del punto di unione con la org.aspectj.lang.JoinPointclasse.


Buona risposta! Finalmente ho capito la differenza!
Dante

2

Sono d'accordo con mgroves .. Un punto di taglio può essere considerato come una raccolta di più punti di giunzione. Punto di giunzione specifica la posizione particolare in cui il consiglio potrebbe essere implementato, dove come punto di taglio riflette l'elenco di tutti i punti di giunzione.


0

JoinPoint: specifica un punto (metodo) nell'applicazione in cui verrà eseguito il Consiglio.

Pointcut: è una combinazione di JoinPoints e specifica quello in cui verrà eseguito JoinPoint Advice.


-5

il punto di unione è un luogo in cui inseriamo effettivamente i consigli

ma il punto di taglio è la raccolta di punti di unione. ciò significa che in quanti modi si configura la logica di taglio trasversale è chiamato il punto di taglio

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.