Red de conocimiento informático - Consumibles informáticos - Entrevistador: ¿Cuál es el orden de ejecución de las anotaciones de Spring @After, @Around, @Before?

Entrevistador: ¿Cuál es el orden de ejecución de las anotaciones de Spring @After, @Around, @Before?

Hay anotaciones @Before, @After, @Around, @AfterRunning, etc. en AOP.

Primero, escriba su propio código y defina la definición de puntos de corte.

Puede verificar la diferencia entre las anotaciones @Before, @After y @Around en Baidu.

En resumen, @Around puede implementar las funciones de @Before y @After, y solo necesita implementarse en un método.

Primero, probemos un método para obtener un registro de la base de datos

El siguiente es el registro impreso por la consola

Puede verlo porque. no hay reglas @Around que coincidan, por lo que no se realizan notificaciones envolventes. (PD: la notificación envolvente que definí significa que debe ajustarse al método en el paquete del controlador y el método debe tener parámetros. El método anterior no tiene parámetros, por lo que solo se utilizan los métodos @before y @after, lo que no cumple con la lógica coincidente de @Around)

Probemos con otro método con parámetros

La siguiente es la impresión de la consola de esta parte del código

Obviamente, esto El método se ajusta a las reglas de coincidencia de notificación envolvente @Around, por lo que se ingresó la lógica de @Around, pero se encontró un problema. Todos los métodos se ejecutaron dos veces, independientemente de la capa de aspecto o la capa de método. (Alguien puede preguntarme si no usé la anotación personalizada @RedisCache(type = Response.class). ¿Por qué cumple con las reglas de coincidencia de @Around? Esto se discutirá a continuación)

analizar los registros Se puede concluir a partir del orden de impresión que al ejecutar el método circundante, el método en @Around se ingresará primero. @Around y publique el código nuevamente.

Después de imprimir las dos primeras líneas de código, el método @Before se ejecutó porque el método ProceedingJoinPoint.proceed() se activó a mitad de camino.

La función de este método es ejecutar el método proxy, lo que significa que después de ejecutar este método, se ejecutará el método de nuestro controlador, y luego se ejecutarán @before y @after, y luego regresarán a @ Para ejecutar el método no ejecutado, @afterRunning se ejecuta en último lugar. Si se lanza una excepción, se puede ejecutar @AfterThrowing

Es decir, el orden de ejecución del wraparound es @Around @Before @After @. Alrededor y las operaciones después de ejecutar ProceedingJoinPoint.proceed() @AfterRunning (Si hay una excepción @AfterThrowing)

Nuestro registro anterior equivale a ejecutar el resultado anterior dos veces. La razón fundamental radica en ProceedingJoinPoint.proceed. () Podemos encontrar que en el método @Around usamos este método dos veces. Sin embargo, cada vez que se llama a este método, @Before @After @Around ejecuta la operación después de ProceedingJoinPoint.proceed() @AfterRunning (si existe). es una excepción @AfterThrowing).

Entonces el problema surge aquí. Entonces, cambiar el código en la sección @Around resolverá el problema. El código después del cambio es el siguiente:

Los resultados de la ejecución después del cambio de código

Volviendo al problema no resuelto anterior, ¿por qué todavía puedo ingresar el método @Around cuando defino otro? anotación del aspecto?

Debido a que nuestro método todavía está bajo el controlador, este requisito se cumple y solo es útil si definimos un controlador bajo el paquete del controlador.

Por ejemplo:

Si el método que acabamos de definir está escrito en TestController, no cumple con las reglas de coincidencia del método @Around ni con @before. y @ después de la regla de anotación, por lo que no coincidirá con ninguna regla. Si necesita hacer coincidir un método específico, puede usar un formulario de anotación personalizado o un método bajo el controlador de funciones

①: formulario de anotación del. característica

Luego agregue la anotación @RedisCache al método requerido y agregue el nombre del método del punto de corte ("annoationPoint ()") a @Before, @After, @Around y otros métodos. hay varias anotaciones que deben coincidir, luego separe con ||

②: especifique el controlador o especifique los métodos bajo el controlador

Esta parte del código especifica todos los métodos bajo UserController en el paquete com.lmx.blog.controller.

El primer * representa que el tipo de retorno no está limitado

El segundo * representa todos los métodos bajo el controlador, (..) representa que los parámetros no están limitados

Cuando un método cumple con las reglas de punto de corte pero no cumple con las reglas de notificación circundantes, la secuencia de ejecución es la siguiente

@Before @After @AfterRunning (si hay una excepción @AfterThrowing)

Cuando el método cumple con las reglas de punto de corte y las reglas de notificaciones circundantes, la secuencia de ejecución es la siguiente

@Around @Antes @Around @Después de las operaciones después de ejecutar ProceedingJoinPoint.proceed( ) @AfterRunning (si hay una excepción @ AfterThrowing)