Primavera (orientado a aspectos AOP)

AOP [Programación orientada a aspectos]

1. ¿Qué es AOP?
AOP (Programación Orientada a Aspectos) se llama: programación orientada a aspectos, que es una idea de programación.
En circunstancias normales, hay dos tipos de requisitos para un sistema / software:
1. Requisitos comerciales: el proceso de realización de una función lógica comercial específica. [Agregar, eliminar, modificar, consultar, etc.]
2. Requisitos del sistema: las funciones que ayudan a mejorar los requisitos comerciales del sistema durante el funcionamiento de todo el sistema [supervisión del rendimiento, gestión de transacciones, inspección de seguridad, almacenamiento en caché, registro, etc. .]
Ahora tenemos que completar La acción consiste en implantar rápidamente los requisitos del sistema en las funciones de requisitos comerciales necesarios donde se deben utilizar los requisitos del sistema.
En este punto, podemos integrar rápidamente la función de requisitos del sistema en la función de requisitos comerciales a través del modo de agente.
Hay dos tipos de modos de proxy: proxy estático y proxy dinámico. El proxy
estático se compone de modo padre-hijo y modo hermano -------- sistema de herencia vertical tradicional [una gran cantidad de escritura repetitiva de código]
proxy dinámico es compuesto por proxy dinámico JDK y proxy dinámico CGLIB --- -Mecanismo de extracción horizontal
Dado que el proxy dinámico JDK solo puede generar objetos proxy para objetos java que tienen interfaces implementadas, no se utilizará como método de operación para implantar rápidamente las funciones necesarias para los requisitos comerciales utilizando funciones de requisitos del sistema.
Proxy dinámico CGLIB, debido a que puede proporcionar objetos proxy para cualquier clase java, fue elegido como la implementación subyacente de AOP [Programación Orientada a Aspectos].
El proxy dinámico CGLIB es la implementación subyacente de Aop.
2. Conceptos relacionados con AOP
joinpoint (punto de conexión): se refiere a aquellos puntos que son interceptados. En primavera, se refiere a un método que se puede utilizar mediante proxy (mejorado). [Método de requisitos empresariales en la clase empresarial]
poingcut (punto de corte): la definición de qué puntos de conexión se interceptan. En Spring, se refiere a métodos que realmente necesitan ser proxy (mejorados).
consejo (información / mejora): se refiere a qué hacer después de interceptar el punto de conexión. Esos códigos (lógica) que están realmente mejorados.
La notificación / mejora se divide en:
notificación previa, notificación posterior, notificación de excepción, notificación final y notificación envolvente.
Aspecto (aspecto): es el proceso combinado de punto de entrada y notificación / mejora.
Introducción (introducción): una notificación especial sin modificar el código de la clase, la introducción puede agregar dinámicamente algunos métodos o campos a la clase en tiempo de ejecución.
target: el objeto de destino del código.
tejido: El proceso de aplicar mejoras a los objetos de destino para crear nuevos objetos proxy. Spring utiliza tejido proxy dinámico. AspectJ utiliza tejido en tiempo de compilación y tejido de instalación de clases.
Proxy (proxy): después de que AOP teje y mejora una clase, se genera una clase de proxy resultante.
Inserte la descripción de la imagen aquí

3. La realización concreta de AOP [Programación Orientada a Aspectos]
Énfasis: Dominar la escritura de expresiones pointcut
Aquí hay algunos ejemplos de expresiones pointcut generales.
1. La ejecución de cualquier método público:
ejecución (público * (...))
2. La
ejecución de cualquier método cuyo nombre comience con "conjunto": ejecución ( conjunto * (...))
3. La ejecución de cualquier método definido por la interfaz
AccountService : ejecución (* com.xyz.service.AccountService. (...))
4. La ejecución de cualquier método definido en el paquete de servicios:
ejecución (
com.xyz.service .. (... ))
5. En el paquete de servicios o sus
subpaquetes, realice cualquiera de los métodos definidos: ejecución (com.xyz.service ... * . (...))
6. la conexión en cualquier punto del paquete de servicios ( ejecución del método solo en Spring AOP):
WITHIN (com.xyz.service. )
7. Cualquier punto de conexión en el paquete de servicio o sus
subpaquetes (solo ejecución de método en Spring AOP): dentro de (com.xyz.service ...
)
8. Cualquier punto de conexión del objeto proxy que implemente la interfaz AccountService (solo ejecución de método en Spring AOP):
este (com.xyz.service.AccountService)
'esto' se usa más comúnmente en la forma de enlace : -ver el aviso a continuación Obtenga información sobre cómo hacer que el objeto proxy esté disponible en el cuerpo de la notificación en la sección.
9. Cualquier punto de conexión del objeto de destino que implemente la interfaz AccountService (solo ejecución de método en Spring AOP):
target (com.xyz.service.AccountService)
'target' se usa más comúnmente en la forma de enlace : -Consulte el aviso 1 a continuación Aprenda cómo hacer que el objeto de destino esté disponible en el cuerpo de notificación en esta sección.
10. Cualquiera solo acepta un parámetro, y el parámetro que se pasa en tiempo de ejecución es el punto de conexión de la interfaz serializable (solo ejecución de método en Spring AOP)
args (java.io.Serializable)
'args' se usa más comúnmente en formularios de enlace : - Consulte la sección de notificación a continuación para saber cómo hacer que los parámetros del método estén disponibles en el cuerpo de la notificación.
Tenga en cuenta que el punto de entrada dado en el ejemplo es diferente de la ejecución (* * (java.io.Serializable)): la versión args solo coincide cuando el parámetro entrante es serializable durante la operación dinámica, y la versión de ejecución se declara en el método firma Coincide con un parámetro de tipo Serializable.
11. Hay un punto de conexión arbitrario anotado con @Transactional en el objeto de destino (solo ejecución de método en Spring AOP)
@target (org.springframework.transaction.annotation.Transactional)
'@target' se usa más comúnmente en formularios vinculantes: -Consulte la sección de notificación a continuación para aprender cómo hacer que el objeto de anotación esté disponible en el cuerpo de la notificación.
12. Cualquier tipo de objeto de destino declarado tiene un punto de conexión de anotación @Transactional (solo ejecución de método en Spring AOP):
@within (org.springframework.transaction.annotation.Transactional)
'@within' es más en la forma de enlace de uso común: -Consulte la sección de notificación a continuación para aprender cómo hacer que el objeto de anotación esté disponible en el cuerpo de la notificación.
13. Cualquier método de ejecución tiene un punto de conexión de anotación @Transactional (solo ejecución de método en Spring AOP)
@annotation (org.springframework.transaction.annotation.Transactional)
'@annotation' se usa más comúnmente en formas vinculantes: - Consulte la sección de notificación a continuación para aprender cómo hacer que el objeto de anotación esté disponible en el cuerpo de la notificación.
14. Cualquiera solo acepta un parámetro, y el tipo de parámetro pasado en tiempo de ejecución tiene un punto de conexión anotado con @Classified (solo ejecución de método en Spring AOP)
@args (com.xyz.security.Classified)
'@args' en It se usa más comúnmente en el formulario vinculante: -Consulte la sección de notificación a continuación para aprender cómo hacer que el objeto de anotación esté disponible en el cuerpo de la notificación.
15 Cualquier punto de conexión en el bean Spring llamado'tradeService '(solo ejecución de método en Spring AOP):
bean (tradeService)
16. Cualquier punto de conexión en un bean Spring cuyo nombre coincida con la expresión comodín '* Servicio' (solo ejecución de método en Spring AOP):
bean (* Servicio)
Por ejemplo:

com.wangxing.spring.bean
StudentBean
public  void  insertStudent();
public  void  insertStudent(Student);
PersonBean
public  void  insertPerson();
public  void  insertPerson(Student);
public  void  deletePerson(int perid);
execution(com.wangxing.spring.bean.*.*(..))
execution(com.wangxing.spring.bean.StudentBean.*(..))
execution(com.wangxing.spring.bean.*.insert*(..))

1. Implementación de AOP basada en archivo XML [archivo de configuración de Spring]

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.1.5.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
  <version>5.1.5.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>5.1.5.RELEASE</version>
</dependency>

package com.wangxing.spring.service;
//业务需求类
public class UserService {
    //添加用户信息的业务方法
    public  void  insertUser(){
        System.out.println("添加用户信息的业务方法");
    }
    //修改用户信息的业务方法
    public  void  updateUser(){
        System.out.println("修改用户信息的业务方法");
        //int a=10/0;
    }
    //删除用户信息的业务方法
    public  void  deleteUser(){
        System.out.println("删除用户信息的业务方法");
    }
    //查询用户信息的业务方法
    public  void  selectUser(){
        System.out.println("查询用户信息的业务方法");
    }
}

package com.wangxing.spring.service;
import org.aspectj.lang.ProceedingJoinPoint;
//增强类/通知类
public class MyAvice {
    //系统需求功能实现方法
    public  void  saveLog(){
        System.out.println("记录执行日志");
    }
    //执行环绕通知的系统需求功能实现方法
    public void testAround(ProceedingJoinPoint joinPoint) throws Throwable{
        saveLog();
        joinPoint.proceed(); // 调用真正的业务方法
        saveLog();
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--创建业务类对象-->
    <bean id="userService" class="com.wangxing.spring.service.UserService"></bean>
    <!--创建增强类/通知类对象-->
    <bean id="myAvice" class="com.wangxing.spring.service.MyAvice"></bean>
    <!--1.基于XML文件【Spring配置文件】的AOP实现-->
    <aop:config>
        <!-- 创建切入点 -->
        <aop:pointcut id="point1" expression="execution(* com.wangxing.spring.service.UserService.select*(..))"/>
        <aop:pointcut id="point2" expression="execution(* com.wangxing.spring.service.UserService.deleteUser(..))"/>
        <aop:pointcut id="point3" expression="execution(* com.wangxing.spring.service.UserService.updateUser())"/>
        <aop:pointcut id="point4" expression="execution(* com.wangxing.spring.service.UserService.insertUser())"/>
        <!--配置切面-->
        <aop:aspect ref="myAvice">
            <!--配置通知【切入点执行增强类方法的位置】-->
            <!--前置通知:切入点对应的业务方法执行之前-->
            <aop:before method="saveLog" pointcut-ref="point1"></aop:before>
            <!--后置通知:切入点对应的业务方法执行之后-->
            <aop:after-returning method="saveLog" pointcut-ref="point2"></aop:after-returning>
            <!--异常通知:切入点对应的业务方法执行出现异常时-->
            <aop:after-throwing method="saveLog" pointcut-ref="point3"></aop:after-throwing>
            <!--环绕通知:切入点对应的业务方法执行之前和执行之后都运行-->
            <aop:around method="testAround" pointcut-ref="point4"></aop:around>
            <aop:after method="saveLog" pointcut-ref="point1"></aop:after>
        </aop:aspect>
    </aop:config>
</beans>

2. Implementación de Aop basada en anotaciones

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.1.5.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
  <version>5.1.5.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>5.1.5.RELEASE</version>
</dependency>

package com.wangxing.spring.service;

import org.springframework.stereotype.Component;

//业务类
@Component("personService")
public class PersonService {
    public  void insertPerson(){
        System.out.println("添加个人信息的业务方法");
    }
    public  void updatePerson(){
        System.out.println("修改个人信息的业务方法");
        //int a=10/0;
    }
    public  void deletePerson(){
        System.out.println("删除个人信息的业务方法");
    }
    public  void selectPerson(){
        System.out.println("查询个人信息的业务方法");
    }
}

package com.wangxing.spring.service;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

//增强类
//@Aspect,表示这个系统需求类是一个切面
@Component
@Aspect
public class MyAvice {
    //系统需求功能实现方法
    //@Before("execution(* com.wangxing.spring.service.PersonService.selectPerson())")
    //@AfterReturning("execution(* com.wangxing.spring.service.PersonService.deletePerson())")
    //@AfterThrowing("execution(* com.wangxing.spring.service.PersonService.updatePerson())")
    @After("execution(* com.wangxing.spring.service.PersonService.updatePerson())")
    public  void  saveLog(){
        System.out.println("记录执行日志");
    }
    //执行环绕通知的系统需求功能实现方法
    @Around("execution(* com.wangxing.spring.service.PersonService.insertPerson())")
    public void testAround(ProceedingJoinPoint joinPoint) throws Throwable{
        saveLog();
        joinPoint.proceed(); // 调用真正的业务方法
        saveLog();
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--使用context命名空间,通知spring扫描指定目录,进行注解的解析-->
    <context:component-scan base-package="com.wangxing.spring.service"></context:component-scan>
    <!--开启aop注解-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

Supongo que te gusta

Origin blog.csdn.net/guoguo0717/article/details/109892356
Recomendado
Clasificación