Spring AOP: ¿Cuál es la diferencia entre JoinPoint y PointCut?

88

Estoy aprendiendo conceptos de Programación Orientada a Aspectos y Spring AOP. No entiendo la diferencia entre un Pointcut y un Joinpoint; ambos parecen ser iguales para mí. Un Pointcut es donde aplica sus consejos y un Joinpoint es también un lugar donde podemos aplicar nuestros consejos. Entonces, ¿cuál es la diferencia?

Un ejemplo de un pointcut puede ser:

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

¿Qué puede ser un ejemplo de Joinpoint?

Saurabh Patil
fuente

Respuestas:

161

Joinpoint: Un joinpoint es un punto candidato en la ejecución del programa de la aplicación donde se puede conectar un aspecto. Este punto podría ser un método llamado, una excepción lanzada o incluso un campo modificado. Estos son los puntos donde el código de su aspecto se puede insertar en el flujo normal de su aplicación para agregar un nuevo comportamiento.

Aviso: este es un objeto que incluye invocaciones de API a las preocupaciones de todo el sistema que representan la acción a realizar en un punto de unión especificado por un punto.

Pointcut: Un pointcut define en qué puntos de unión se deben aplicar los consejos asociados. El asesoramiento se puede aplicar en cualquier punto de unión compatible con el marco AOP. Por supuesto, no desea aplicar todos sus aspectos en todos los puntos de unión posibles. Los puntos le permiten especificar dónde desea que se apliquen sus consejos. A menudo, usted especifica estos puntos de acceso utilizando nombres de métodos y clases explícitos o mediante expresiones regulares que definen patrones de nombres de métodos y clases coincidentes. Algunos marcos de AOP le permiten crear puntos de acceso dinámicos que determinan si aplicar consejos basados ​​en decisiones en tiempo de ejecución, como el valor de los parámetros del método.

La siguiente imagen puede ayudarlo a comprender Advice, PointCut, Joinpoints. ingrese la descripción de la imagen aquí

Fuente

Explicación usando la analogía del restaurante: Fuente de @Victor

Cuando vas a un restaurante, miras un menú y ves varias opciones para elegir. Puede pedir uno o más de los elementos del menú. Pero hasta que los pidas, son solo "oportunidades para cenar". Una vez que haces el pedido y el camarero lo lleva a tu mesa, es una comida.

Los puntos de unión son opciones en el menú y los puntos de acceso son elementos que selecciona.

Un Joinpoint es una oportunidad dentro del código para que aplique un aspecto ... solo una oportunidad. Una vez que aproveche esa oportunidad y seleccione uno o más Joinpoints y les aplique un aspecto, obtendrá un Pointcut.

Fuente Wiki :

Un punto de unión es un punto en el flujo de control de un programa donde el flujo de control puede llegar a través de dos rutas diferentes (IMO: por eso llamar a la unión).

El aviso describe una clase de funciones que modifican otras funciones

Un pointcut es un conjunto de puntos de unión.

Premraj
fuente
3
Esto debe marcarse como respuesta correcta. Solo para agregar más información, mire la respuesta de Cragi Walls ... coderanch.com/t/485525/Spring/Difference-Joint-Point-Point-Cut .
Victor
2
Al grano: un punto define en qué puntos de unión se deben aplicar los consejos +1
Gala Naman
¿Solo para confirmación, more Joinpoints and apply an aspect to them, you've got a Pointcut. aspecto o consejo para ellos?
Asif Mushtaq
@Premraj Entonces, según su analogía, el consejo será ordenar la comida. Estoy en lo cierto?
Vishwas Atrey
La analogía del restaurante ayudó a aclarar la confusión entre JoinPoints y pointcuts, ¡Gracias!
SM
30

Para comprender la diferencia entre un punto de unión y un corte de punto, piense en los cortes de puntos como especificando las reglas de tejido y los puntos de unión como situaciones que satisfacen esas reglas.

En el siguiente ejemplo,

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

Pointcut define reglas que dicen, los consejos deben aplicarse sobre el método getName () presente en cualquier clase en cualquier paquete y joinpoints será una lista de todos los métodos getName () presentes en las clases para que se puedan aplicar consejos sobre estos métodos.

(En el caso de Spring, Rule se aplicará solo en beans administrados y los consejos solo se pueden aplicar a métodos públicos).

Sujay Mumbaraddi
fuente
1
"Pointcut define las reglas diciendo, los consejos deben aplicarse sobre el método getName () presente en cualquier clase en cualquier paquete y joinpoints será una lista de todos los métodos getName () presentes en las clases para que los consejos puedan aplicarse sobre estos métodos". Lo siento, pero esto se está volviendo más confuso. ¿Me puede dar una analogía en un escenario de la vida cotidiana del mundo real?
Saurabh Patil
28

JoinPoints: estos son básicamente lugares en la lógica empresarial real donde desea insertar algunas funciones diversas que son necesarias pero que no forman parte de la lógica empresarial real. Algunos ejemplos de JoinPints ​​son: llamada de método, método que regresa normalmente, método que lanza una excepción, instancia de un objeto, referencia de un objeto, etc.

Atajos de puntos: los cortes de puntos son algo así como expresiones regulares que se utilizan para identificar puntos de unión. Los pontcuts se expresan usando "lenguaje de expresión de pointcut". Los pointcuts son puntos de flujo de ejecución donde se debe aplicar la preocupación transversal. Existe una diferencia entre Joinpoint y Pointcut; Los puntos de unión son más generales y representan cualquier flujo de control en el que 'podemos optar por' introducir una preocupación transversal, mientras que pointcuts identifica los puntos de unión en los que 'queremos' introducir una preocupación transversal.

Krishna
fuente
1
Joinpoint: lugares potenciales para aplicar / ejecutar el código de asesoramiento. Pointcut: puntos de unión elegidos reales para ejecutar el consejo.
user104309
24

Explicación simple para alguien que es nuevo en los conceptos AOP. Esto no es exhaustivo, pero debería ayudar a comprender los conceptos. Si ya está familiarizado con la jerga básica, puede dejar de leer ahora.

Suponga que tiene una clase Empleado normal y desea hacer algo cada vez que se llaman a estos métodos.

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

estos métodos se denominan JoinPoints . Necesitamos una forma de identificar estos métodos para que el marco pueda encontrar los métodos, entre todas las clases. Métodos que ha cargado. Entonces escribiremos una expresión regular para que coincida con la firma de estos métodos. Si bien hay más, como verá a continuación, pero vagamente esta expresión regular es lo que define Pointcut . p.ej

* * mypackage.Employee.get*(*)

Primero * es para el modificador público / privado / protegido / predeterminado. El segundo * es para el tipo de retorno del método.

Pero luego también necesitas decir dos cosas más:

  1. ¿Cuándo se debe realizar una acción? Por ejemplo, antes / después de la ejecución del método O en caso de excepción
  2. ¿Qué debería hacer cuando coincide (tal vez solo imprima un mensaje)

La combinación de estos dos se llama Consejo .

Como puede imaginar, tendría que escribir una función para poder hacer # 2. Entonces, así es como podría verse para lo básico.

Nota: Para mayor claridad, use la palabra REGEX en lugar de * * mypackage.Employee.get*(*). En realidad, la expresión completa entra en la definición.

@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 vez que comiences a usarlos bastante, podrías terminar especificando muchos consejos @ After / @ Before / @ Around. Las expresiones regulares repetidas eventualmente terminarán haciendo las cosas confusas y difíciles de mantener. Entonces, lo que hacemos, simplemente le damos un nombre a la expresión y la usamos en cualquier otro lugar de la clase 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() {....}

Por cierto, también querrás envolver toda esta lógica en una clase, que se llama Aspecto y escribirías una clase:

@Aspect
public class MyAwesomeAspect{....}

Para que todas estas cosas funcionen, tendría que decirle a Spring que analice las clases para leer, comprender y tomar medidas sobre las palabras clave @ AOP. Una forma de hacerlo es especificando lo siguiente en el archivo xml de configuración de primavera:

<aop:aspectj-autoproxy>

Dev S
fuente
1
Soy nuevo en AOP y esta explicación me ayudó a comprender la relación entre Advice / Pointcuts / JoinPoints con bastante claridad.
Jatin Shashoo
11

Al comparar un lenguaje AOP como AspectJ con un lenguaje de consulta de datos como SQL, puede pensar en puntos de unión (es decir, todos los lugares en su código donde puede tejer código de aspecto) como una tabla de base de datos con muchas filas. Un pointcut es como un SELECT stamement que puede elegir un subconjunto definido por el usuario de filas / puntos de unión. El código real que teje en esos lugares seleccionados se llama consejo.

kriegaex
fuente
9

Definiciones

Según la documentación:

Punto de unión: un punto durante la ejecución de un programa, como la ejecución de un método o el manejo de una excepción.

Puede considerar Joint Points como eventos en ejecución de un programa. Si está utilizando Spring AOP, esto incluso se limita a la invocación de métodos. AspectJ proporciona más flexibilidad.

Pero nunca manejas todos los eventos, ya que no comes toda la comida del menú cuando vas a un restaurante (no te conozco, ¡podrías! Pero, ciertamente no lo hago). Así que haces una selección de eventos para manejar y qué hacer con ellos. Aquí va Pointcuts . Según la documentación,

Pointcut : un predicado que coincide con los puntos de unión .

Luego asocias qué hacer con el Pointcut , ahí va Advice . Según la documentación,

El aviso está asociado con una expresión de corte de punto y se ejecuta en cualquier punto de unión que coincida con el corte de punto.

Código

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
    }

}

Explicación del código

  • ExampleBusinessClass cuando se utiliza proxy, ¡es nuestro objetivo!
  • doYourBusiness()es un posible punto de articulación
  • SomeAspect es nuestro aspecto el que atraviesa múltiples preocupaciones como ExampleBusinessClass
  • somePointCut()es una definición de un corte de punto que coincide con nuestro punto de unión
  • afterSomePointCut()es un consejo que se ejecutará después de nuestro somePointCut corte de punto que coincide con doYourBusiness() el punto de unión
  • beforeSomePointCut()también es un consejo que coincide con todas las publicejecuciones de métodos. A diferencia afterSomePointCut, este usa una declaración de corte de punto en línea

Puedes mirar la documentación si no me crees. espero que esto ayude

Amanuel Nega
fuente
1
Explicación sencilla. Solo tres textos citados son suficientes para comprender. Gracias.
TRiNE
6

Ambos pertenecen al "dónde" de la programación orientada a aspectos.

Un punto de unión es un lugar individual donde puede ejecutar código con AOP. Por ejemplo, "cuando un método lanza una excepción".

Un pointcut es una colección de puntos de unión. Por ejemplo, "cuando un método de la clase Foo lanza una excepción".

Matthew Groves
fuente
4

JoinPoint : Joinpoint son puntos en la ejecución de su programa donde el flujo de ejecución cambió, como la captura de excepciones, la llamada a otro método.

PointCut : PointCut son básicamente esos Joinpoints donde puede poner su consejo (o aspecto de llamada).

Entonces, básicamente, PointCuts es el subconjunto de JoinPoints .

Vikas Bhardwaj
fuente
3

AOP en primavera tiene {Advisor, Advice, Pointcut, Joinpoint}

Como saben, el propósito principal de aop es desvincular la lógica de preocupación transversal (Aspecto) del código de la aplicación, para implementar esto en Spring usamos (Advice / Advisor)

Pointcut se usa para filtrar dónde queremos aplicar este consejo exactamente, como "todos los métodos comienzan con insertar", por lo que se excluirán otros métodos, por eso tenemos en la interfaz de Pointcut {ClassFilter y MethodMatcher}

Por lo tanto, Advice es la implementación de la lógica transversal y Advisor es el consejo más el PointCut, si usa solo el asesoramiento, Spring lo asignará al asesor y hará que el pointcut sea VERDADERO, lo que significa que no bloquee nada. Es por eso que cuando usa solo consejos, se aplica a todos los métodos de la clase objetivo porque no los filtró.

Pero Joinpoint es una ubicación en el programa, puedes pensar en ello como un reflejo cuando accedes al objeto Class y luego puedes obtener el objeto Method, luego puedes invocar cualquier método en esta clase, y así es como funciona el compilador, si piensas como esto se puede imaginar el Joinpoint.

Joinpoint puede ser con campo, constructor o método pero en Spring tenemos joinpoint solo con métodos, es por eso que en Spring tenemos (Before, After, Throws, Around) tipos de Joinpoint, todos ellos se refieren a ubicaciones en la clase.

Como mencioné, puede tener consejos sin pointcut (sin filtro), luego se aplicará a todos los métodos o puede tener un asesor que es [consejo + pointcut] que se aplicará a métodos específicos pero no puede tener un consejo sin joinpoint como pointcut, debe especificarlo, y es por eso que los tipos de consejos en primavera son exactamente los mismos que el punto de unión, por lo que cuando elige un consejo, implícitamente elige qué punto de unión.

Para concluir, el consejo es la lógica de implementación para su aspecto a la clase de destino, este consejo debe tener un punto de unión como antes de la invocación, después de la invocación, después de lanzar o alrededor de la invocación, luego puede filtrar dónde exactamente desea aplicarlo usando pointcut to filtrar los métodos o sin pointcut (sin filtro) para que se aplique a todos los métodos de la clase.

Ahmad
fuente
3

Un pointcut se define en la implementación de la clase Aspect. El corte de puntos se refiere básicamente a la expresión del corte de puntos dentro del consejo.

Por ejemplo,

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

Lo anterior significa que se llama al método "includeAddOns" antes de invocar (debido al consejo de @Before) cualquier método (en clases dentro del paquete "app.purchase2.service.impl")

Toda la anotación se llama pointcut @Before("execution(* app.purchase2.service.impl.*(..))")

El punto conjunto es la invocación del método real, que unió el método del paquete "app.purchase2.service.impl" al método de la clase de aspecto "includeAddOns ()".

Puede acceder a las propiedades del punto de unión con la org.aspectj.lang.JoinPointclase.

Mira esto
fuente
¡Buena respuesta! ¡Por fin entendí la diferencia!
Dante
2

Estoy de acuerdo con mgroves .. Un corte de punto puede considerarse como una colección de múltiples puntos de unión. Punto de unión especifique la ubicación particular donde se podría implementar el consejo, donde como punto de corte refleja la lista de todos los puntos de unión.

yonikawa
fuente
0

JoinPoint: Especifica un punto (método) en la aplicación donde se ejecutará el Advice.

Pointcut: es una combinación de JoinPoints, y especifica en qué punto se ejecutará el consejo de JoinPoint.

Akash5288
fuente
-5

punto de unión es un lugar donde realmente colocamos los consejos

pero el corte de puntos es la colección de puntos de unión. eso significa que de cuántas maneras colocamos la lógica transversal se llama corte de punto

usuario4327697
fuente