Spring AOP: Quelle est la différence entre JoinPoint et PointCut?


88

J'apprends les concepts de programmation orientée aspect et Spring AOP. Je n'arrive pas à comprendre la différence entre un Pointcut et un Joinpoint - les deux semblent être les mêmes pour moi. Un Pointcut est l'endroit où vous appliquez vos conseils et un Joinpoint est également un endroit où nous pouvons appliquer nos conseils. Alors quelle est la différence?

Un exemple de coupe de point peut être:

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

Quel peut être un exemple de Joinpoint?

Réponses:


161

Point de jointure: un point de jointure est un point candidat dans l' exécution du programme de l'application où un aspect peut être branché. Ce point peut être une méthode appelée, une exception levée ou même un champ en cours de modification. Ce sont les points où le code de votre aspect peut être inséré dans le flux normal de votre application pour ajouter un nouveau comportement.

Conseil: Il s'agit d'un objet qui inclut des appels d'API aux préoccupations à l'échelle du système représentant l'action à effectuer à un point de jonction spécifié par un point.

Pointcut: Un pointcut définit à quels points de jonction, les conseils associés doivent être appliqués. Les conseils peuvent être appliqués à n'importe quel point de jonction pris en charge par le framework AOP. Bien sûr, vous ne voulez pas appliquer tous vos aspects à tous les points de jonction possibles. Les pointcuts vous permettent de spécifier où vous souhaitez appliquer vos conseils. Souvent, vous spécifiez ces pointcuts à l'aide de noms de classe et de méthode explicites ou via des expressions régulières qui définissent des modèles de nom de classe et de méthode correspondants. Certains frameworks AOP vous permettent de créer des pointcuts dynamiques qui déterminent s'il faut appliquer des conseils en fonction de décisions d'exécution, telles que la valeur des paramètres de méthode.

L'image suivante peut vous aider à comprendre Advice, PointCut, Joinpoints. entrez la description de l'image ici

La source

Explication utilisant l'analogie du restaurant: Source par @Victor

Lorsque vous sortez dans un restaurant, vous regardez un menu et voyez plusieurs options à choisir. Vous pouvez commander un ou plusieurs des éléments du menu. Mais jusqu'à ce que vous les commandiez, ce ne sont que des «occasions de dîner». Une fois que vous passez la commande et que le serveur l'apporte à votre table, c'est un repas.

Les points de jonction sont des options du menu et les points de raccourci sont des éléments que vous sélectionnez.

Un Joinpoint est une opportunité dans le code pour vous d'appliquer un aspect ... juste une opportunité. Une fois que vous saisissez cette opportunité, sélectionnez un ou plusieurs points de jonction et leur appliquez un aspect, vous obtenez un pointcut.

Wiki source :

Un point de jointure est un point dans le flux de contrôle d'un programme où le flux de contrôle peut arriver via deux chemins différents (IMO: c'est pourquoi appeler joint).

Advice décrit une classe de fonctions qui modifient d'autres fonctions

Un pointcut est un ensemble de points de jointure.


3
Cela doit être marqué comme une bonne réponse. Juste pour ajouter quelques informations, regardez la réponse Cragi Walls ... coderanch.com/t/485525/Spring/Difference-Joint-Point-Point-Cut .
Victor

2
Au point: un pointcut définit à quels points de jonction les conseils doivent être appliqués +1
Gala Naman

Juste pour confirmation, more Joinpoints and apply an aspect to them, you've got a Pointcut. aspect à eux ou conseil à eux?
Asif Mushtaq

@Premraj Donc, selon votre analogie, le conseil commandera le repas. Ai-je raison?
Vishwas Atrey

L'analogie du restaurant a aidé à dissiper la confusion entre les JoinPoints et les pointcuts, merci!
SM

30

Pour comprendre la différence entre un point de jointure et un point de coupe, pensez aux points de coupe comme spécifiant les règles de tissage et les points de jointure comme des situations satisfaisant à ces règles.

Dans l'exemple ci-dessous,

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

Pointcut définit des règles disant que les conseils doivent être appliqués sur la méthode getName () présente dans n'importe quelle classe de n'importe quel package et les points de jointure seront une liste de toutes les méthodes getName () présentes dans les classes afin que les conseils puissent être appliqués sur ces méthodes.

(Dans le cas de Spring, la règle sera appliquée uniquement aux beans gérés et les conseils ne peuvent être appliqués qu'aux méthodes publiques).


1
"Pointcut définit des règles disant, les conseils doivent être appliqués sur la méthode getName () présente dans n'importe quelle classe dans n'importe quel package et les points de jointure seront une liste de toutes les méthodes getName () présentes dans les classes afin que les conseils puissent être appliqués sur ces méthodes." Je suis désolé mais cela devient de plus en plus déroutant. Pouvez-vous s'il vous plaît me donner une analogie dans un scénario de la vie quotidienne dans le monde réel?
Saurabh Patil

28

JoinPoints: ce sont essentiellement des endroits dans la logique métier réelle où vous souhaitez insérer des fonctionnalités diverses qui sont nécessaires mais ne font pas partie de la logique métier réelle. Quelques exemples de JoinPints ​​sont: appel de méthode, méthode retournant normalement, méthode lançant une exception, instanciation d'un objet, référençant un objet, etc ...

Pointcuts: les pointcuts sont quelque chose comme des expressions régulières qui sont utilisées pour identifier les points de jointure. Les Pontcuts sont exprimés en utilisant un "langage d'expression pointcut". Les découpes sont des points de flux d'exécution où la préoccupation transversale doit être appliquée. Il existe une différence entre Joinpoint et Pointcut; Les points de jonction sont plus généraux et représentent tout flux de contrôle dans lequel nous «pouvons choisir» d'introduire une préoccupation transversale, tandis que les points de jonction identifient de tels points de jonction où «nous voulons» introduire une préoccupation transversale.


1
Joinpoint - Lieux potentiels pour appliquer / exécuter le code de conseil. Pointcut - points de jonction réellement choisis pour exécuter le conseil.
user104309

24

Explication profane pour quelqu'un qui est nouveau dans les concepts AOP. Ce n'est pas exhaustif, mais devrait aider à appréhender les concepts. Si vous connaissez déjà le jargon de base, vous pouvez arrêter de lire maintenant.

Supposons que vous ayez un employé de classe normal et que vous vouliez faire quelque chose à chaque fois que ces méthodes sont appelées.

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

ces méthodes sont appelées JoinPoints . Nous avons besoin d'un moyen d'identifier ces méthodes afin que le framework puisse trouver les méthodes, parmi toutes les classes.methods qu'il a chargées. Nous allons donc écrire une expression régulière correspondant à la signature de ces méthodes. Bien qu'il y ait plus, comme vous le verrez ci-dessous, mais vaguement cette expression régulière est ce qui définit Pointcut . par exemple

* * mypackage.Employee.get*(*)

Le premier * est pour le modificateur public / privé / protégé / par défaut. Le deuxième * correspond au type de retour de la méthode.

Mais vous devez également dire deux autres choses:

  1. Quand une action doit-elle être entreprise - par exemple avant / après l'exécution de la méthode OU en cas d'exception
  2. Que doit-il faire quand il correspond (peut-être simplement imprimer un message)

La combinaison de ces deux est appelée Conseil .

Comme vous pouvez l'imaginer, il vous faudrait écrire une fonction pour pouvoir faire # 2. Voici donc à quoi cela pourrait ressembler pour les bases.

Remarque: pour plus de clarté, utilisez le mot REGEX au lieu du * * mypackage.Employee.get*(*). En réalité, l'expression complète entre dans la définition.

@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

Une fois que vous commencez à les utiliser un peu, vous pourriez finir par spécifier de nombreux conseils @ After / @ Before / @ Around. Les expressions régulières répétées finiront par rendre les choses confuses et difficiles à maintenir. Donc ce que nous faisons, nous donnons simplement un nom à l'expression et l'utilisons partout ailleurs dans la 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() {....}

BTW, vous voudriez également envelopper toute cette logique dans une classe, qui s'appelle Aspect et vous écririez une classe:

@Aspect
public class MyAwesomeAspect{....}

Pour que toutes ces choses fonctionnent, vous devriez dire à Spring d'analyser les classes pour lire, comprendre et agir sur les mots-clés @ AOP. Une façon de le faire est de spécifier ce qui suit dans le fichier xml de configuration de printemps:

<aop:aspectj-autoproxy>


1
Je suis nouveau sur AOP et cette explication m'a aidé à comprendre assez clairement la relation entre les Conseils / Pointcuts / JoinPoints.
Jatin Shashoo

11

En comparant un langage AOP comme AspectJ à un langage de requête de données comme SQL, vous pouvez considérer les points de jointure (c'est-à-dire tous les endroits de votre code où vous pouvez tisser le code d'aspect) comme une table de base de données avec de nombreuses lignes. Un pointcut est comme un stamement SELECT qui peut choisir un sous-ensemble défini par l'utilisateur de lignes / points de jointure. Le code réel que vous intégrez à ces endroits sélectionnés est appelé conseil.


9

Définitions

Selon la documentation:

Point de jointure: un point lors de l'exécution d'un programme, tel que l'exécution d'une méthode ou la gestion d'une exception.

Vous pouvez considérer les points communs comme des événements lors de l'exécution d'un programme. Si vous utilisez Spring AOP, cela se limite même à l'appel de méthodes. AspectJ offre plus de flexibilité.

Mais vous ne gérez jamais tous les événements car vous ne mangez pas toute la nourriture du menu lorsque vous allez au restaurant (je ne vous connais pas, vous pourriez! Mais, certainement pas). Vous faites donc une sélection d'événements à gérer et que faire avec eux. Voici Pointcuts . Selon la documentation,

Pointcut : un prédicat qui correspond aux points de jointure .

Ensuite, vous associez quoi faire avec le pointcut , il y a des conseils . Selon la documentation,

Le conseil est associé à une expression de coupe de point et s'exécute à tout point de jointure correspondant au point de coupe.

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
    }

}

Explication du code

  • ExampleBusinessClass quand proxy-ed, est notre cible!
  • doYourBusiness()est un point commun possible
  • SomeAspect est notre aspect qui croise dans de multiples préoccupations telles que le cul ExampleBusinessClass
  • somePointCut()est une définition d'un point coupé qui correspond à notre point de joint
  • afterSomePointCut()est un conseil qui sera exécuté après notre somePointCut coupe de point qui correspond au doYourBusiness() point commun
  • beforeSomePointCut()est également un conseil qui correspond à toutes les publicexécutions de méthode. Contrairement à afterSomePointCut, celui-ci utilise une déclaration de coupure de point en ligne

Vous pouvez consulter la documentation si vous ne me croyez pas. J'espère que ça aide


1
Explication simple. Seuls trois textes cités suffisent à comprendre. Merci.
TRiNE

6

Les deux concernent le «où» de la programmation orientée aspect.

Un point de jointure est un emplacement individuel où vous pouvez exécuter du code avec AOP. Par exemple, "lorsqu'une méthode lève une exception".

Un pointcut est une collection de points de jointure. Par exemple, "lorsqu'une méthode de la classe Foo lève une exception".


4

JoinPoint : Joinpoint sont des points dans l'exécution de votre programme où le flux d'exécution a été modifié comme la capture d'exception, l'appel d'une autre méthode.

PointCut : PointCut sont essentiellement ces points de jonction où vous pouvez mettre vos conseils (ou appeler l'aspect).

Donc, essentiellement, les PointCuts sont le sous-ensemble des JoinPoints .


3

AOP au printemps a {Advisor, Advice, Pointcut, Joinpoint}

Comme vous le savez, l'objectif principal d'aop est de découpler la logique de préoccupation transversale (Aspect) du code de l'application, pour l'implémenter au printemps, nous utilisons (Advice / Advisor)

Pointcut est utilisé pour filtrer où nous voulons appliquer exactement ce conseil, comme "toutes les méthodes commencent par insérer", donc les autres méthodes seront exclues, c'est pourquoi nous avons dans l'interface Pointcut {ClassFilter et MethodMatcher}

Donc, Advice est la mise en œuvre de la logique transversale et Advisor est le conseil plus le PointCut, si vous n'utilisez que des conseils, le ressort le mappera au conseiller et rendra le pointcut VRAI, ce qui signifie ne rien bloquer. C'est pourquoi lorsque vous n'utilisez que des conseils, il est appliqué à toutes les méthodes de la classe cible car vous ne les avez pas filtrées.

Mais Joinpoint est un emplacement dans le programme, vous pouvez y penser comme une réflexion lorsque vous accédez à l'objet Class, puis vous pouvez obtenir l'objet Method, puis vous pouvez invoquer n'importe quelle méthode de cette classe, et c'est ainsi que fonctionne le compilateur, si vous pensez cela, vous pouvez imaginer le Joinpoint.

Joinpoint peut être avec un champ, un constructeur ou une méthode, mais au printemps, nous avons un point de jointure avec des méthodes uniquement, c'est pourquoi, au printemps, nous avons des types de Joinpoint (Avant, Après, Lancer, Autour), tous faisant référence à des emplacements dans la classe.

Comme je l'ai mentionné, vous pouvez avoir des conseils sans découpage (pas de filtre) puis ils seront appliqués à toutes les méthodes ou vous pouvez avoir un conseiller qui est [conseil + découpage] qui sera appliqué à des méthodes spécifiques mais vous ne pouvez pas avoir de conseils sans point de jointure comme pointcut, vous devez le spécifier, et c'est pourquoi les types de conseils dans spring sont exactement les mêmes types que le point de jointure, donc lorsque vous choisissez un conseil, vous choisissez implicitement quel point de jointure.

Pour conclure, le conseil est la logique d'implémentation de votre aspect à la classe cible, ce conseil doit avoir un point de jonction comme avant l'invocation, après l'invocation, après le lancement ou autour de l'invocation, puis vous pouvez filtrer où exactement vous voulez l'appliquer en utilisant le pointcut to filtrer les méthodes ou pas de pointcut (pas de filtre) pour qu'il soit appliqué à toutes les méthodes de la classe.


3

Un pointcut est défini sur l'implémentation de la classe Aspect. La coupure de point se réfère essentiellement à l'expression de coupure de point dans le conseil.

Par exemple,

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

Cela signifie que la méthode "includeAddOns" est appelée avant d'appeler (en raison du conseil @Before) des méthodes (dans les classes du package "app.purchase2.service.impl")

L'annotation entière s'appelle le pointcut @Before("execution(* app.purchase2.service.impl.*(..))")

Le point commun est l'appel de méthode réel, qui a joint la méthode du package "app.purchase2.service.impl" à la méthode de la classe d'aspect "includeAddOns ()".

Vous pouvez accéder aux propriétés du point de jonction avec la org.aspectj.lang.JoinPointclasse.


Bonne réponse! Enfin j'ai compris la différence!
Dante le

2

Je suis d'accord avec mgroves .. Une coupe ponctuelle peut être considérée comme une collection de plusieurs points de jonction. Point de jonction spécifiez l'emplacement particulier où l'avis pourrait être mis en œuvre, où comme point de jonction reflète la liste de tous les points de jonction.


0

JoinPoint: Il spécifie un point (méthode) dans l'application où les conseils seront exécutés.

Pointcut: C'est une combinaison de JoinPoints, et il spécifie à quel point JoinPoint Advice sera exécuté.


-5

point de jointure est un endroit où nous plaçons réellement les conseils

mais le point coupé est la collection de points de jonction. cela signifie combien de façons nous con place la logique transversale est appelée la coupe de point

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.