SpringBoot实现AOP详解

SpringBoot实现AOP详解

1. Spring框架实现AOP

  • 首先我们知道
  • Aspect(切面) === Advice(通知) + PointCut(切入点)
  • Advice(通知): 业务逻辑中一些附加操作称之为通知,可分为前置,后置,环绕,异常,最终。
  • PointCut(切入点):配置通知应用于项目中的具体哪些操作

1.1 类 implement xxAdvice接口

1.2 xml进行配置

<!-- 配置aop切面   -->
<aop:config>
    <!--   配置切入点  within表示在指定的包中   -->
    <aop:pointcut id="pc" expression="execution(返回值 包.类.方法名(方法参数)) | within(类级别)"/>
    <!--   切面 = 通知 + 切入点     -->
    <aop:advisor advice-ref="通知类" pointcut-ref="pc"/>
</aop:config>

2. SpringBoot配置AOP的方式

2.1  主要是对现有的spring框架进行封装

  • 无xml配置,一切都是java进行配置

  • AOP:面向切面

  • Aspect(切面) === Advice(通知) + PointCut(切入点)

  • 所以仍要需要做的两件事:

    • 开发附加操作(通知)Advice
    • 配置切入点 &组装切面

2.2 面向切面编程的步骤

  • 引入aop切面的编程依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
  • 在SpringBoot中新建MyAdviceConfig配置类
package com.liu.aop.config;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.context.annotation.Configuration;


// 表示当前的类是一个配置类
@Configuration
//该注解只能用在类上,作用:代表当前类是一个切面类,等价于spring.xml中的<aop:config>标签
//所以现在有了<aop:config>切面,还需要  通知 + 切入点
// 切面 == 通知 + 切面
@Aspect
public class MyAdviceConfig {

    /**
     * @param joinPoint
     * @Before:前置通知 
     * value:切入点表达式  二者加起来构建成为一个切面
     * JoinPoint:连接点:可以理解为两个圆形的切点,从这个切点就可以获取到当前执行的目标类及方法
     * 前置通知和后置通知的参数的都是 JoinPoint, 前置后置通知都没有返回值
     */
    // 方法级别:具体到某个具体的方法
    // @Before(value = "execution(* com.liu.aop.service.impl.*.*(..))")
    // 表示service包下的所有类所有方法都执行该前置通知
    @Before(value = "within(com.liu.aop.service.*)")
    public void before(JoinPoint joinPoint) {
        System.out.println("before开始执行查询.......");
        System.out.println("正在执行的目标类是: " + joinPoint.getTarget());
        System.out.println("正在执行的目标方法是: " + joinPoint.getSignature().getName());
    }

    /**
     * 后置通知,属性参数同上面的前置通知
     * @param joinPoint 前置通知和后置通知独有的参数
     */
    @After(value = "execution(* com.liu.aop.service.impl.*.*(..))")
    public void after(JoinPoint joinPoint) {
        System.out.println("after查询结束.......");
        // 获取执行目标类和方法名等等
    }

    /**
     * @param proceedingJoinPoint 环绕通知的正在执行中的连接点(这是环绕通知独有的参数)
     * @return 目标方法执行的返回值
     * @Around: 环绕通知,有返回值,环绕通知必须进行放行方法(就相当于拦截器),否则目标方法无法执行
     */
    @Around(value = "execution(* com.liu.aop.service.impl.*.*(..))")
    public Object aroud(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("aroud环绕通知开始.......");
        System.out.println("执行的目标类 = " + proceedingJoinPoint.getTarget());
        System.out.println("执行的目标方法 = " + proceedingJoinPoint.getSignature().getName());
        // 必须方法目标方法
        Object proceed = proceedingJoinPoint.proceed();
        System.out.println("aroud环绕通知结束.......");
        // 将目标方法的返回值进行返回,否则调用目标方法的方法无法获取到返回值
        return proceed;
    }
}

版权声明:程序员胖胖胖虎阿 发表于 2022年8月31日 上午9:00。
转载请注明:SpringBoot实现AOP详解 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...