world supported hello designators baeldung spring aop aspectj spring-aop pointcut

spring - supported - AOP de primavera: ¿Cuál es la diferencia entre JoinPoint y PointCut?



spring boot aop (13)

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 los mismos para mí. A Pointcut es donde aplica su asesoramiento y un punto de unión es también un lugar donde podemos aplicar nuestro asesoramiento, entonces, ¿cuál es la diferencia?

Un ejemplo de un punto clave puede ser:

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

¿Qué puede ser un ejemplo de un punto de unión?


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 Puntos Conjuntos como eventos en la 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 en el menú cuando vas a un restaurante (¡no te conozco, podrías! Pero, desde luego, no). Entonces, usted hace una selección de eventos para manejar y qué hacer con ellos. Aquí va Pointcuts . De acuerdo con la documentación,

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

Luego, asocias qué hacer con Pointcut , ahí va Asesoramiento . De acuerdo con la documentación,

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

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 before 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 proxy-ed, es nuestro objetivo!
  • doYourBusiness() es un posible punto de unión
  • SomeAspect es nuestro aspecto que se cruza con múltiples preocupaciones, como por ejemplo ExampleBusinessClass
  • somePointCut() es una definición de un punto de corte que coincide con nuestro punto de unión
  • afterSomePointCut() es un consejo que se ejecutará después de nuestro corte de doYourBusiness() que coincide con el punto de unión doYourBusiness()
  • beforeSomePointCut() es también un consejo que coincide con todas public ejecuciones de métodos public . A diferencia de afterSomePointCut , este usa una declaración de corte de punto en línea

Puedes mirar la documentation si no me crees. espero que esto ayude


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

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

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

Así que el asesoramiento es la implementación de la lógica transversal y el asesor es el consejo más el PointCut; si solo usa el consejo, spring lo correlacionará con el asesor y hará que el corte de punto sea VERDADERO, lo que significa que no debe bloquear 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 pensarlo como 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 así esto te puedes imaginar el punto de unión.

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

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

Para concluir, el consejo es la lógica de implementación para su aspecto a la clase objetivo, este consejo debe tener un punto de unión como antes de la invocación, después de la invocación, después del lanzamiento o alrededor de la invocación, entonces puede filtrar dónde exactamente quiere aplicarlo usando punto filtre los métodos o no corte puntos (sin filtro) para que se aplique a todos los métodos de la clase.


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 el código de aspecto) como una tabla de base de datos con muchas filas. Un corte puntual es como un archivo SELECT que puede elegir un subconjunto definido por el usuario de filas / puntos de unión. El código real que entrelaza en esos lugares seleccionados se llama consejo.


Ambas 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 arroja una excepción".

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


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


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

Suponga que tiene un empleado de clase normal y desea hacer algo cada vez que se invocan estos métodos.

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

estos métodos se llaman 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. Por lo tanto, escribiremos una expresión regular para que coincida con la firma de estos métodos. Si bien hay más en ello, como verás a continuación, pero de forma general 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 devolución del método.

Pero también debes contar dos cosas más:

  1. ¿Cuándo debe tomarse 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 coincida (tal vez simplemente imprimir un mensaje)

La combinación de estos dos se llama Consejo .

Como puedes imaginar, deberías escribir una función para poder hacer # 2. Así que así es como podría parecer lo básico.

Nota: Para mayor claridad, use la palabra REGEX en lugar del * * 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 usar estos un poco, 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, qué hacemos, simplemente le damos un nombre a la expresión y la usamos en todos los demás lugares 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ías envolver toda esta lógica en una clase, que se llama Aspect y escribirías una clase:

@Aspect public class MyAwesomeAspect{....}

Para que todo esto funcione, debería decirle a Spring que analice las clases para leer, comprender y tomar medidas con las palabras clave @ AOP. Una forma de hacerlo es especificar lo siguiente en el archivo spring config xml:

<aop:aspectj-autoproxy>


Para comprender la diferencia entre un punto de unión y un punto de corte, piense que los puntos de corte especifican 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, el consejo debe aplicarse en 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 el consejo pueda aplicarse a estos métodos.

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


Un pointcut se define en el aspecto: implementación de clase. El corte de punto básicamente se refiere a la expresión de corte de punto 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 @Before) cualquier método (en las clases dentro del paquete "app.purchase2.service.impl")

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

Punto de unión es la invocación de método real, que se unió al método en el paquete "app.purchase2.service.impl" al método en la clase de aspecto "includeAddOns ()".

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


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

pero el punto de corte es la colección de puntos de unión. eso significa que la forma en que contamos la lógica transversal se llama punto de corte


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

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


JoinPoint : Joinpoint son puntos en la ejecución de su programa donde el flujo de ejecución cambió como Exception catching, Calling other method.

PointCut : PointCut son básicamente esos puntos de unión donde puedes poner tu consejo (o aspecto de llamada).

Básicamente, PointCuts es el subconjunto de JoinPoints .


Punto de unión: Un punto de unión 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 invocado, una excepción lanzada o incluso un campo que se está modificando. 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.

Consejo: Este es un objeto que incluye invocaciones de API a las preocupaciones generales del 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 debe aplicar el Consejo asociado. El asesoramiento se puede aplicar en cualquier punto de unión compatible con el marco de AOP. Por supuesto, no desea aplicar todos sus aspectos en todos los puntos de unión posibles. Los puntos de corte le permiten especificar dónde desea que se aplique su consejo. A menudo se especifican estos puntos de referencia utilizando nombres explícitos de clase y método o mediante expresiones regulares que definen patrones de clase y nombre de método coincidentes. Algunos marcos de trabajo de AOP le permiten crear puntos de corte dinámicos que determinan si se debe aplicar un asesoramiento basado en decisiones de tiempo de ejecución, como el valor de los parámetros del método.

La siguiente imagen puede ayudarlo a comprender Advice, PointCut, Joinpoints.

Source

Explicación usando Restaurant Analogy: Fuente de @Victor

Cuando sales a un restaurante, miras un menú y ves varias opciones para elegir. Puede pedir uno o más de cualquiera de los artículos en el menú. Pero hasta que realmente los pidas, son solo "oportunidades para cenar". Una vez que haces el pedido y el camarero lo trae a tu mesa, es una comida.

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

Un punto de unión es una oportunidad dentro del código para que aplique un aspecto ... solo una oportunidad. Una vez que aprovechas esa oportunidad y seleccionas uno o más puntos de unión y les aplicas un aspecto, obtienes un Pointcut.


Puntos de unión: estos son básicamente lugares en la lógica empresarial real donde desea insertar alguna funcionalidad miscelánea que es necesaria pero que no forma parte de la lógica comercial real. Algunos ejemplos de JoinPints ​​son: llamada al método, método que retorna normalmente, método que arroja una excepción, crear instancias de un objeto, referir un objeto, etc.

Pointcuts: Pointcuts son algo así como expresiones regulares que se utilizan para identificar joinpoints. Los Pontcuts se expresan usando "lenguaje de expresión puntual". Los Pointcuts son puntos de flujo de ejecución donde se debe aplicar la preocupación transversal. Hay una diferencia entre Joinpoint y Pointcut; Los puntos de unión son más generales y representan cualquier flujo de control donde ''podemos elegir'' introducir una preocupación transversal, mientras que los puntos de corte identifican tales puntos de unión donde ''queremos'' introducir una preocupación transversal.