springboot 整合 AOP切面编程

文章目录

  • 什么是AOP切面编程
  • AOP中重要概念
    • 切面
    • 连接点
    • 通知
    • 切入点
  • springboot的切面编程的步骤
    • 引入切面编程依赖
    • 开发附加操作(在springboot项目新建config配置)

什么是AOP切面编程

所谓AOP就是一种编程范例,我们一般做一个项目,会分为很多个模块,这些模块中有很多不同的功能,功能中有很多不同的切入点,举个例子,现在我们有一个保存用户业务逻辑功能,我们需要在保存用户之前输入一句话,这句话必须在保存用户之前做到,一般对我们springboot项目中,针对这样的情况,我们就会在Service层的代码中加入一行,如下图所示:

===================保存用户业务逻辑=================
用户业务
UserService

  void save(User user)

  void delete(Integer id);

  User queryById(Integer id);

  ....


UserServiceImpl implement UserService

  void save(User user){
  	sout("=============");//业务功能-1
  	...
  	userDao.save(user);
  }

 

但是你想过没有,假设我们又要在删除用户的逻辑中也输出这样的一行内容呢?
我们是不是又要在业务逻辑层中又增加这样的一行呢?

  void delete(Integer id){
	sout("=============");//业务功能-1
	......
  	userDao.delete(id);
  }

那如果我们的其他模块的功能结构也需要这样这样的功能,那岂不是我们都要去加入这一行,这岂不是很麻烦吗?所以我们引入了AOP,我们能把这个要加入的功能,作为一个关注点切入进去,就不用交织在每个模块的代码中,而是作为一个单独的模块存在。
从这里我们就可以发现AOP解决了两个问题:一个是代码混乱,核心的业务逻辑代码还必须兼顾其他功能,这就导致不同功能的代码交织到一起,可读性很差。
第二,是代码分散问题。同一个功能代码分散在多个模块中,不易维护。

AOP中重要概念

切面

切面(Aspect)由切点(Pointcut)和通知(Advice)组成,它既包含了横切逻辑的定义,也包括了连接点的定义。

连接点

应用执行过程中能够插入切面的一个点,这个点可以是方法调用时,抛出异常时,甚至修改字段时。切面代码可以利用这些点插入到应用的正常流程之中,并添加新的行为。
总的来说,就是程序执行的某一刻的,在这个点可以做的额外操作。

通知

切面的工作被称之为通知。

切入点

切入点是用来描述连接点的,它决定了当前代码与连接点匹配

我们可以简单的把 AOP 理解为贯穿于方法之中,在方法执行前、执行时、执行后、返回值后、异常后要执行的操作。

springboot的切面编程的步骤

引入切面编程依赖

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-aopartifactId>
dependency>

开发附加操作(在springboot项目新建config配置)

/**
 * 自定义切面配置类
 */
@Configuration //代表这个类是spring的配置类
@Aspect //代表这个类是切面配置类
public class MyAspectConfig {
    //切面Aspect=Advice附加操作+Pointcut切入点

    @Before("execution(* com.demo.springbootaoptest.service.*.*(..))")//代表这是一个核心业务逻辑执行之前的附加操作,value属性表明切书店
    public void before(JoinPoint joinPoint){
        System.out.println("=========前置附加操作=========");
        System.out.println("当前执行目标类: "+ joinPoint.getTarget());
        System.out.println("当前执行目标类中方法: "+ joinPoint.getSignature().getName());
    }
    @After("execution(* com.demo.springbootaoptest.service.*.*(..))")
    public void after(){
        System.out.println("后置通知");
    }
    @Around("execution(* com.demo.springbootaoptest.service.*.*(..))")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    System.out.println("==========进入环绕的前置操作===========");
    System.out.println("当前执行类: "+proceedingJoinPoint.getTarget());
    System.out.println("方法名: "+proceedingJoinPoint.getSignature().getName());
    //放心目标方法执行
    Object proceed = proceedingJoinPoint.proceed();//继续处理  业务逻辑方法执行
    System.out.println("==========进入环绕的后置操作===========");
    return null;
}  
}

我对这上面的注解一一进行解释

  • @Aspect 用来类上,代表这个类是一个切面
  • @Before 用在方法上代表这个方法是一个前置通知方法
  • @After 用在方法上代表这个方法是一个后置通知方法
  • @Around 用在方法上代表这个方法是一个环绕的方法

另外这个方法是 上述 的 execution() 方法,用于匹配需要被 AOP 切入的方法。

execution() 方法的参数有以下几个:

"*" 表示匹配任意类型的方法。
com.demo.springbootaoptest.service 表示匹配 com.demo.springbootaoptest.service 包下的所有类。
.* 表示匹配所有类的所有方法。
(..) 表示匹配方法的任意参数。

service类

public class UserService {
   public void save(String name){
//       System.out.println("===========================");//=》额外操作
        System.out.println("处理save核心业务逻辑,调用mapper");
    }
    public void delete(Integer id) {
        System.out.println("===========================");

        System.out.println("处理delete核心业务逻辑,调用mapper");

    }
    public void update(String name){
        System.out.println("处理update核心业务逻辑,调用mapper");


    }
    public String find(String name){
        System.out.println("处理find核心业务逻辑,调用mapper");
        return name;
    }
}

前置结果
springboot 整合 AOP切面编程_第1张图片

后置结果
在这里插入图片描述

环绕结果
这里要特别解释一下环绕通知的流程

在方法执行前,打印一条日志,表示进入环绕的前置操作。
获取目标方法的执行类和方法名。
调用 proceed() 方法,让目标方法执行。
在方法执行后,打印一条日志,表示进入环绕的后置操作。
springboot 整合 AOP切面编程_第2张图片

你可能感兴趣的:(spring,boot,java,后端)