1. Introducción
Durante el proceso de desarrollo, a menudo necesitamos escribir muchos ejemplos:
@GetMapping ("/id/get") Resultado público GetByID (ID de cadena) arroja excepción {log.info ("El parámetro de solicitud es:"+id); Verificar (nuevo VerifyParam ("ID de departamento", ID)); Resultado de resultado = nuevo resultado ("obtenido con éxito a través de ID!", Service.QueryById (id)); log.info ("El mensaje de retorno es:"+resultado.toString ()); resultado de retorno; }Imprima los parámetros de solicitud y los parámetros de retorno, y estas operaciones existen en cada método, lo que hace que nuestro código sea más redundante. Por esta razón, podemos usar proxy dinámico para usar parámetros de impresión e imprimir mensajes de retorno como secciones, y usar expresiones de corte de puntos para cortarlos en cada método.
2. Pasos
1. Introducir dependencias relacionadas con AOP:
<
Después de introducir dependencias, Spring-AOP cargará las dependencias que necesita. Spring usa SuppectJ de forma predeterminada para implementar notificaciones.
Entre ellos, SuppeJweaver.jar contiene archivos que analizan las expresiones de corte de puntos de SuppeJ. Esta dependencia también se requiere al usar expresiones de corte de punto para manejar las transacciones.
2. Configuración:
1) Crear una clase de configuración:
/*** @Function Descripción: clase AOP utilizada para operaciones de capa de controlador* @author administrador*/ @componente // manejar objetos para surgir para administrar @Aspect // Representa esta clase como una clase de aspecto Controleraop {}La anotación de @Aspect representa que es una clase de gestión de aspectos, donde se pueden definir expresiones de corte puntual, y el marco SUPSJ lo analizará.
2) Defina la expresión de corte de punto:
@PointCut ("Ejecution (public*com.hzt.manage.*. Web.controller ..*.*(..))") // PointCut Expression public void privilege () {}Donde @Pointcut representa este método como una expresión de corte de punto. Su valor es una expresión de corte puntual, donde se puede omitir el valor y su formato aproximado es:
@Annotation (formato de expresión de etiqueta de expresión)
Para el formato, los indicadores de corte de punto SUPPEJ compatibles con Spring AOP son los siguientes:
1. Ejecución: el punto de conexión utilizado para que coincida con la ejecución del método;
2. Dentro: se usa para que coincida con la ejecución de métodos dentro del tipo especificado;
3. Este: método de ejecución utilizado para que coincida con el tipo de objeto AOP proxy actual; Tenga en cuenta que el tipo de coincidencia del objeto AOP proxy, que puede incluir la introducción de interfaces y la coincidencia de tipo;
4. Objetivo: método de ejecución utilizado para que coincida con el tipo de objeto de destino actual; Tenga en cuenta que la coincidencia de tipo del objeto de destino es la coincidencia de tipo, de modo que no se incluya la introducción de la interfaz;
5. Args: el método de ejecución se utiliza para que coincida con los parámetros pasados por el método ejecutado actualmente como el tipo especificado;
6. @Within: se usa para que coincida con los métodos de mantenimiento dentro del tipo de anotación especificado;
7. @Target: método de ejecución utilizado para que coincida con el tipo de objeto de destino actual, donde el objeto de destino contiene la anotación especificada;
8. @Args: se usa para que coincida con la ejecución de los parámetros aprobados en el método ejecutado actualmente que contiene la anotación especificada;
9. @Annotation: se usa para que coincida con el método que actualmente ejecuta el método contiene la anotación especificada;
10. Bean: Spring AOP Extension, SuppeJ no tiene un método de ejecución para hacer coincidir los objetos de frijoles con un nombre específico;
11. Punto de referencia: significa referirse a otros puntos de entrada de nombres, solo el estilo @apectj lo admite, pero no al estilo de esquema.
Args define los parámetros al ejecutar el método de expresión de corte de punto:
@PointCut (value = "Ejecution (public*com.hzt.manage.*. Web.controller ..*.*(..)) && args (param)", argnames = "param") // expresión de puntos public void privilege1 (string param) {}Nos centramos en la expresión del punto de conexión del método de ejecución, y su estructura aproximada es:
Ejecución (modificadores-patern?
1.
2. La coincidencia de valor de retorno (RET-Type-Pattern) puede representar cualquier valor de retorno para *, como (cadena) representa solo filtrar el punto de entrada que devuelve el tipo de cadena, nombres de clase de la ruta completa, etc. (no se puede omitir)
3. Declarando el patrón de tipo? Por ejemplo, *.Manage representa el paquete de primer nivel como arbitrario y el paquete de segundo nivel como el nombre de la administración. *.. Manay representa los paquetes de subclase en todos los paquetes de administración. com .. *. Comtroller representa todos los paquetes de controlador en paquetes COM, etc., y * significa que todos los paquetes coinciden. (No omitido)
4. Método Nombre de coincidencia (Name-Pattern) puede especificar el nombre del método o * representa todo, Get * representa todos los métodos que comienzan con Get, o puede especificar el prefijo * Get representa cualquier método con sufijo arbitrario de GET (no omitido)
5. Parámetro coincidencia ((parámetro)) puede especificar un tipo de parámetro específico, los parámetros múltiples están separados por ", y cada parámetro también puede ser"*"para que coincidan con los parámetros de cualquier tipo, como (cadena) significa un método para que coincida con un parámetro de cadena; (*, Cadena) significa un método para que coincida con dos parámetros, el primer parámetro puede ser de cualquier tipo, y el segundo parámetro es de un tipo de cadena; (..) se puede usar para representar cualquier parámetro (no se omite)
6. Matriota de tipo de excepción (¿Patrón de lanzamiento?)
3. Defina el método de faceta
@Around ("privilege ()") objeto público alrededor (procedimientojoinpoint pjd) lanza lando {// obtener el nombre de método string className = pjd.getSignature (). GetClass (). GetName (); // Obtener el nombre del método de ejecución String MethodName = PJD.GetSignature (). GetName (); / ** Impresión del registro de inicialización*/ logger log = loggerFactory.getLogger (className); // Defina el objeto de parámetro de retorno resultado = nulo; // Registre el tiempo de inicio Long Start = System.CurrentTimemillis (); // Objeto de parámetros de método GET [] args = pjd.getArgs (); String Params = "Los parámetros de solicitud de front-end son:"; // Obtenga la colección de parámetros de solicitud y traverse y empalme para (objeto objeto: args) {params + = object.ToString () + ","; } params = params.substring (0, params.length () - 1); // Imprime el parámetro de parámetro de solicitud log.info (classname + "class" + MethodName + "" + Params); // Ejecutar el método de destino resultado = pjd.proceed (); // Imprima el mensaje de retorno log.info ("El método devuelve el mensaje como:" + (resultado instancia de resultados? (Resultado) resultado: resultado)); // Obtenga el tiempo de ejecución log.info (MethodName + "El tiempo de ejecución del método es:" + (System.CurrentTimemillis () - Start)); resultado de retorno; }5. @La notificación envolvente de relieve, como se muestra en el código anterior, es la notificación envolvente, que tiene el parámetro de punto de procedimiento
Donde el pjd.proceed (); El método representa la ejecución del método de destino y obteniendo un valor de retorno del tipo de objeto. Podemos procesar el valor de retorno, como el procesamiento de decoración, etc.
El valor de retorno es el resultado de la ejecución del método. En el código anterior, primero obtiene el nombre de clase, el nombre del método, los parámetros de solicitud de método, etc., realiza la impresión de empalme y registra la hora de inicio de la ejecución del método y lo imprime al registro.
Luego ejecute el método, obtenga el resultado de retorno del método, imprima el tiempo de ejecución y el resultado de ejecución.
Finalmente, se devuelve el resultado de la ejecución. Es decir, la sección AOP codifica el mensaje de solicitud y el mensaje de retorno se completa.
Donde @around lo representa como un método de notificación circundante, tiene los siguientes tipos:
1. @Before previa-notificación, que tiene el punto de unión del parámetro de solicitud, que se utiliza para conectar los detalles de conexión del punto de conexión actual, generalmente incluyendo el nombre del método y el valor del parámetro. El cuerpo del método se ejecuta antes de ejecutar el método, y los parámetros del método no se pueden cambiar, ni los resultados de la ejecución del método no se pueden cambiar.
@Before (valor = "privilegio ()") public void antes (unión unión de unión) {}2. @After Post Notificación: Notificación de que la ejecución se realiza independientemente de si se produce una excepción después de ejecutar el método de destino. En la post-notificación, no se puede acceder al resultado de ejecución del método de destino (porque puede ocurrir una excepción), y el resultado de ejecución del método no se puede cambiar.
@Before (valor = "privilegio ()") public void después (unión unión de unión) {}3. @AfterReturning Devuelve una notificación. La notificación que se ejecuta solo cuando se ejecuta el método de destino es la misma que el método post-aranged. Puede acceder al resultado de ejecución del método (debido a la ejecución normal) y los detalles de conexión del método, pero no puede cambiar el resultado de la ejecución del método.
@AfterReturning (value = "privilege ()") public void después de la toma (unePoint unePoint, resultado del objeto) {}El valor de retorno almacenado en el resultado es el método.
4. @Afterthrowing Notificación de excepción: código que se ejecutará solo cuando ocurra una excepción en el método de destino. El atributo de lanzamiento representa una excepción lanzada durante la ejecución del cuerpo del método, y su valor debe ser consistente con el valor de excepción en el método.
@Afterthrowing (valor = "privilegio ()", shrowing = "ex") public void excede (unión de unión de unión, excepción ex) {}3. Prueba
Escribir un método de controlador
@RestController@requestMapping ("/API/V1/Dept") Public Class DeptController extiende BASECONTROLLER {/** clase de registro*/private logger log = loggerFactory.getLogger (getClass ()); / ** Mi propio servicio*/ @@AUTOWIREDIREDIRDRED SERVICE DE SERVICE DEL PRIVAD; /*** @Function Descripción: Método para consultar el contenido del departamento basado en ID* @return Dept*/@getMapping ("/id/get") Resultado público GetByid (ID de cadena) lanza la excepción {verify (nueva verifyParam ("ID de departamento", id)); devolver nuevo resultado ("obtenido con éxito a través de ID!", Service.QueryById (ID)); }}De esta manera, el método en nuestra capa de controlador es muy conciso.
Resultados de la prueba:
2018-04-10 22: 59: 27.468 Información 1460 --- [NIO-8088-EXEC-5] NproCedingjoinPoint $ MethodSignatureImpl: El parámetro de solicitud front-end de GetByid es: 22
2018-04-10 22:59:27.470 INFO 1460 --- [nio-8088-exec-5] nProceedingJoinPoint$MethodSignatureImpl: The method returns the message as:Result [result_code=suc, result_message=Successfully obtained department information through id!, data=Dept [id=22, no=22, name=22, manager=22, description=22, phone=22, CreateTime = Thu 19 de abril 23:38:37 CST 2018, EditTime = Null]]
2018-04-10 22: 59: 27.470 Información 1460 --- [NIO-8088-EXEC-5] NproCedingjoinPoint $ MethodSignatureImpl: El tiempo de ejecución del método GetByID es: 2
¡Esto le permite imprimir parámetros de solicitud, devolver resultados, tiempo de ejecución, etc. con impresión elegante, concisa y concisa!