Spring-AOP (punto de entrada y notificación)

1.1 Expresión de corte de puntos

1.1.1 Directorio de proyectos

1.1.2 Descripción de etiquetas de uso común

# <aop: config>

Rol: declarar la configuración aop

# <aop: aspecto> :

Función: configura el
atributo de aspecto : id: identifica de forma única el nombre del aspecto ref: hace referencia al id del bean de clase de notificación

# <aop: pointcut>

Función: configurar la expresión del punto de entrada
Atributo: id: identificar de forma única la expresión del punto de entrada expresión del nombre: definir la expresión del punto de entrada

1.1.3 Ejemplo de código

Servicio al Cliente

package cn.guardwhy.service;
/**
 * 客户service接口
 */
public interface CustomerService {
    
    
    /**
     * 保存客户
     */
    void saveCustomer();

    /**
     * 根据客户id查询客户
     */
    void findCustomerById(Integer id);
}

CustomerServiceImpl

package cn.guardwhy.service.impl;

import cn.guardwhy.service.CustomerService;
/**
 * 客户service实现类
 */
public class CustomerServiceImpl implements CustomerService {
    
    
    @Override
    public void saveCustomer() {
    
    
        System.out.println("保存客户操作");
    }

    @Override
    public void findCustomerById(Integer id) {
    
    
        // 根据客户id查询客户
        System.out.println("根据客户id查询客户,客户id: " + id);
    }
}

LogAdvice

package cn.guardwhy.advice;
/**
 * 日志通知
 */
public class LogAdvice {
    
    
    /**
     * 记录用户操作日志
     */
    public void printLog(){
    
    
        System.out.println("记录用户操作日志");
    }
}

bean.xml

<?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">
    <!--配置客户service-->
    <bean id="customerService" class="cn.guardwhy.service.impl.CustomerServiceImpl"></bean>

    <!--配置日志通知-->
    <bean id="logAdvice" class="cn.guardwhy.advice.LogAdvice"></bean>

<!--配置aop:四个步骤-->
    <aop:config>
        <aop:aspect id="logAspect" ref="logAdvice">
            <aop:before method="printLog" pointcut-ref="pt1"></aop:before>

            <!--切入点表达式演化
                表达式组成:
                    访问修饰符  返回值  包名称 类名称  方法名称 (参数列表)
                演化过程:
                    全匹配模式:
                        public void com.itheima.service.impl.CustomerServiceImpl.saveCustomer()
                    访问修饰符可以省略:
                        void com.itheima.service.impl.CustomerServiceImpl.saveCustomer()
                    返回值可以使用通配符:*
                        * com.itheima.service.impl.CustomerServiceImpl.saveCustomer()
                    包名称可以使用通配符:*(有多少个包,就需要多少个*)
                        * *.*.*.*.CustomerServiceImpl.saveCustomer()
                    类名称可以使用通配符:*
                        * *.*.*.*.*.saveCustomer()
                    方法名称可以使用通配符:*
                        * *.*.*.*.*.*()
                    参数列表可以使用通配符:*(此时必须要有参数)
                        * *.*.*.*.*.*(*)
                    参数列表可以使用:..(有无参数都可以)
                        * *.*.*.*.*.*(..)
            -->
            <aop:pointcut id="pt1" expression="execution(* cn.guardwhy.service..*.*(..))"></aop:pointcut>
        </aop:aspect>
    </aop:config>
</beans>

CustomerController

package cn.guardwhy.controller;

import cn.guardwhy.service.CustomerService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 客户表现层
 */
public class CustomerController {
    
    
    public static void main(String[] args) {
    
    
        // 1.加载spring配置文件,创建spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");
        // 2.获取客户service
        CustomerService customerService = (CustomerService) context.getBean("customerService");
        // 3.保存客户
        customerService.saveCustomer();
        // 4.根据客户id查询客户
        customerService.findCustomerById(1);
    }
}

Los resultados

2.1 Tipos de notificación

2.1.1 Directorio de proyectos

2.1.2 Conceptos básicos de notificaciones comunes

# <aop: antes>

作用:配置前置通知,在目标方法执行前执行
属性:
    method:指定通知方法名称
    pointcut:定义切入点表达式
    pointcut-ref:引用切入点表达式的id

# <aop: after-return>

作用:配置后置通知,无论目标方法正常返回,还是发生异常都会执行。
属性:
    method:指定通知方法名称
    pointcut:定义切入点表达式
    pointcut-ref:引用切入点表达式的id

# <aop: after-throwing>

作用:配置异常通知,在目标方法发生异常后执行。它和后置通知只能执行一个.
属性:
    method:指定通知方法名称
    pointcut:定义切入点表达式
    pointcut-ref:引用切入点表达式的id

# <aop: after>

作用:配置最终通知,在目标方法正常返回后执行。它和异常通知只能执行一个.
属性:
    method:指定通知方法名称.
    pointcut:定义切入点表达式.
    pointcut-ref:引用切入点表达式的id.

# <aop: alrededor>

作用:配置环绕通知,综合了前面四类通知,可以手动控制通知的执行时间点和顺序
属性:
    method:指定通知方法名称
    pointcut:定义切入点表达式
    pointcut-ref:引用切入点表达式的id

2.1.3 Ejemplo de código

LogAdvice

package cn.guardwhy.advice;

import org.aspectj.lang.ProceedingJoinPoint;

/**
 * 日志通知
 */
public class LogAdvice {
    
    
    /**
     * 前置通知
     */
    public void beforeLog(){
    
    
        System.out.println("[前置通知]记录用户操作日志");
    }

    /**
     * 后置通知
     */
    public  void afterReturningLog(){
    
    
        System.out.println("【后置通知】记录用户操作日志");
    }

    /**
     * 异常通知
     */
    public  void afterThrowingLog(){
    
    
        System.out.println("【异常通知】记录用户操作日志");
    }

    /**
     * 最终通知
     */
    public  void afterLog(){
    
    
        System.out.println("【最终通知】记录用户操作日志");
    }

    /**
     * 环绕通知:
     *      1.它是spring框架为我们提供了手动控制通知执行时间点和顺序的一种特殊通知类型
     * 原理分析:
     *      2.spring框架提供了ProceedingJoinPoint接口,作为环绕通知的参数。在环绕通知
     *      执行的时候,spring框架会提供实例化对象,我们直接使用即可。该接口中提供了
     *      两个方法:
     *          getArgs:获取参数列表
     *          proceed:相当于反射中的invoke方法
     *
     */
    public void aroundLog(ProceedingJoinPoint pjp){
    
    
        // 前置通知
        System.out.println("[环绕通知-前置通知]记录用户操作日志");

        try {
    
    
            // 获取参数列表
            Object[] args = pjp.getArgs();
            // 反射调用目标方法
            Object retv = pjp.proceed(args);
            // 后置通知
            System.out.println("[环绕通知-后置通知]记录用户操作日志");
        } catch (Throwable throwable) {
    
    
            throwable.printStackTrace();
            // 异常通知
            System.out.println("[环绕通知-异常通知]记录用户操作日志");
        }
        // 最终通知
        System.out.println("[环绕通知-最终通知]记录用户操作日志");
    }
}

Configurar bean.xml

<?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">
    <!--配置客户service-->
    <bean id="customerService" class="cn.guardwhy.service.impl.CustomerServiceImpl"/>

    <!--配置日志通知-->
    <bean id="logAdvice" class="cn.guardwhy.advice.LogAdvice"/>

    <!--配置aop -->
    <aop:config>
        <aop:aspect id="logAspect" ref="logAdvice">
            <!--前置通知-->
            <aop:before method="beforeLog" pointcut-ref="pt1"/>
            <!--后置通知-->
            <aop:after-returning method="afterReturningLog" pointcut-ref="pt1"/>
            <!--异常通知-->
            <aop:after-throwing method="afterThrowingLog" pointcut-ref="pt1"/>
            <!--最终通知-->
            <aop:after method="afterLog" pointcut-ref="pt1"/>
            
            <!--环绕通知-->
            <aop:around method="aroundLog" pointcut-ref="pt1"/>
            <!--切入点表达式-->
            <aop:pointcut id="pt1" expression="execution(* cn.guardwhy.service..*.*(..))"/>
        </aop:aspect>
    </aop:config>
</beans>

CustomerController

package cn.guardwhy.controller;

import cn.guardwhy.service.CustomerService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 客户表现层
 */
public class CustomerController {
    
    
    public static void main(String[] args) {
    
    
        // 1.加载spring配置文件,创建spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");
        // 2.获取客户service
        CustomerService customerService = (CustomerService) context.getBean("customerService");
        // 3.保存客户
        customerService.saveCustomer();
    }
}

Resultados de la

Supongo que te gusta

Origin blog.csdn.net/hxy1625309592/article/details/115101791
Recomendado
Clasificación