【Spring AOP】Spring AOP快速使用

2023-11-06

前言

Aop 是面向切面编程,项目中一般都使用aop做日志、权限等操作,比如我们想要打印所有接口的日志,就可以用Aop来实现。
下面用一个打印接口的日志来讲述Aop的快速使用。

如果你不想知道Aop的一些具体注解的单独讲述,可以直接进入到案例,案例中也会对Aop的注解做讲述和使用。


1、相关注解

类注解

  • @Aspect :表明是一个切面类;

方法注解

  • @Pointcut :切入点,该注解表示从哪里做切入;
  • @Before :前置通知,在切入点之前执行,可以理解成调用接口或者方法之前执行;
  • @After :后置通知,在切入点之后执行,可以理解成调用完该接口或者方法之后执行;
  • @AfterRuturning :返回通知,可以理解成调用完该接口或者方法返回结果之后执行;
  • @AfterThrowing :异常通知,可以理解成调用该接口或者方法时出现异常之后执行;
  • @Around :环绕通知,可以理解成这一个注解用来控制调用接口或方法;

2、execution 表达式

execution 表达式 写法是:访问修饰符 返回值 包名.包名.包名…类名.方法名(参数列表)


例一【execution 表达式 的限制使用】

下面这个例子,展示一些详细的使用

execution(public com.api.controller.User.findUserByUserId(..))

public 是该方法的返回值
com.api.controller 是该类所在的包位置
User 是类名
findUserByUserId 是该类的方法名
(..) 这个是参数,.. 表示通配所有参数


例二【execution 表达式 的通配使用】

execution(* com.api.controller..*.*(..))

第一个 * 是通配返回值
com.api.controller 是该类所在的包位置
.* 是通配com.api.controller这个包下所有的类
* 是类中所有方法
(..) 表示通配所有参数


3、相关pom依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

4、案例

在做案例之前,先创建一个测试接口,方便测试Aop。

创建接口

package com.api.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RequestMapping("/user")
@RestController
public class UserController {

    @GetMapping("/findUserByUserId")
    public String findUserByUserId(@RequestParam(value = "userId") String userId) {
        log.info("进入 findUserByUserId 接口 参数userId: {}", userId);
        return "findUserByUserId 接口 返回的数据";
    }

}

Aop使用 方式一【@Before 、@After 、@AfterRuturning、@AfterThrowing版】

package com.api.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;


@Component
@Aspect
@Slf4j
public class AOPTest {

    // @Pointcut 注解的作用就是要根据一种规则切入到某个位置, 我在这里使用的是 execution 表达式规则
    @Pointcut("execution(* com.api.controller..*.*(..))")
    public void pointcut() {
    }

    /***
     * 前置通知
     */
    @Before("pointcut()")
    public void deBefore(JoinPoint joinPoint) {
        log.info("前置通知");
        log.info("参数 {}", joinPoint.getArgs());
        final Signature signature = joinPoint.getSignature();
        log.info("接口名称 name {}", signature.getName());
        log.info("类名 declaringTypeName {}", signature.getDeclaringTypeName());

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        log.info("接口地址 {}", request.getRequestURL().toString());
        log.info("接口请求方式 {}", request.getMethod());

    }

    /***
     * 后置通知
     */
    @After("pointcut()")
    public void after(JoinPoint joinPoint){
        log.info("后置通知");
    }

    /***
     * 返回结果通知
     */
    @AfterReturning(returning = "o", pointcut = "pointcut()")
    public void afterReturning(Object o) {
        log.info("返回结果通知");
        log.info("结果 {}", o);
    }

    /***
     * 异常通知
     */
    @AfterThrowing(throwing = "e", pointcut = "pointcut()")
    public void afterThrowing(JoinPoint joinPoint, Exception e){
        log.info("异常通知");
        log.info("产生异常的方法 {}", joinPoint);
        log.info("异常种类 {}", e);
    }
}

接下来调用一下刚刚写的接口,打印日志如下:

在这里插入图片描述

执行顺序图如下:

在这里插入图片描述

先进入前置通知,执行接口,如果接口中出现异常就进入异常通知,无异常进入结果通知,最后进入后置通知。


Aop使用 方式二【@Around版】

package com.api.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;


@Component
@Aspect
@Slf4j
public class AOPTest {

    // @Pointcut 注解的作用就是要根据一种规则切入到某个位置, 我在这里使用的是 execution 表达式
    @Pointcut("execution(* com.api.controller..*.*(..))")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object Around(ProceedingJoinPoint joinPoint) {
        log.info("前置通知");
        log.info("参数 {}", joinPoint.getArgs());
        final Signature signature = joinPoint.getSignature();
        log.info("接口名称 name {}", signature.getName());
        log.info("类名 declaringTypeName {}", signature.getDeclaringTypeName());
        Object proceed = null;
        try {
            // 进入接口
            proceed = joinPoint.proceed();
            log.info("返回结果通知");
            
        } catch (Throwable throwable) {
            log.info("异常通知");
            throw new RuntimeException(throwable);
            
        } finally {
            log.info("后置通知");
            
        }

        return proceed;
    }
}

接下来调用一下刚刚写的接口,打印日志如下:

在这里插入图片描述





End


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Spring AOP】Spring AOP快速使用 的相关文章

随机推荐

  • 小程序如何获取手机系统相关信息

    小程序如何获取手机系统信息的方法是 调用 wx getSystemInfo 此接口 通过此接口 可以获取到手机的品牌 型号 像素比 操作系统等信息 微信小程序代码举例 wx getSystemInfo model true 获取手机型号 s
  • Upload-labs-master-Pass-02通关教程——类型绕过

    注意 刷题的时候记得清理之前上传的文件 以免出现干扰 1 先上传准备好的mm php 2 查看代码它对文件的类型进行了查看 3 使用Burp Suit来结束数据包并修改文件类型 然后转发后进入链接 成功绕过 这一关数据文件类型绕过
  • react 数据监听

    监听组件传递的值 componentWillReceiveProps newProps 参数为给组件传递的参数 监听组件内部状态的变化 componentDidUpdate prevProps prevState 参数分别为改变之前的数据状
  • SSH_Unable to negotiate with 192.168.1.152 port 22: nomatching host host key type found. Their offer...

    操作环境 Kali Linux 终端远程登录ssh时 提示如下错误 Unable to negotiate with 192 168 1 152 port 22 nomatching host host key type found The
  • [Python http.server] 搭建http服务器用于下载/上传文件

    动机 笔者需测试bs架构下的文件上传与下载性能 故想通过Python搭建http服务器并实现客户端与服务器之间的文件上传和下载需求 难点 这应该是很基础的东西 不过笔者之前未接触过http编程 谨在此记录下学习的过程 可能不是最优解 方法
  • RabbitMq消息堆积问题及惰性队列

    消息堆积问题 当生产者发送消息的速度超过了消费者处理的速度 就会导致队列的消息堆积 知道队列存储消息达到上限 最早接受的消息 可能就会成为死信 会被丢弃 这就是消息堆积问题 解决消费对接问题 1 增加更多的消费者 提高消费者速度 2 在消费
  • java war tomcat 部署_Tomcat部署java web项目,war包方式

    今天做的网站要上线了 部署的过程中遇到许多问题 在这里记录一下 步骤 项目采用war包的形式发布 war包的生成 使用idea中的maven project中的install命令 一般可以先clean一下 安装tomcat 8和java 1
  • 欧洲最大时尚电商平台工程师:如何使用测试容器进行功能测试

    一直以来 我们探索如何在基于Java的后端应用程序中使用Testcontainers org库编写功能测试 在本文中 我将展示Zalando Marketing Services的团队如何使用功能测试 然后 我们将讨论一个基于 Spring
  • 纯Numpy实现多层神经网络

    纯Numpy实现多层神经网络 本文分为以下几个内容 1 实现层的逻辑结构 2 实现各种激活函数 3 实现Dense层 4 实现前向传播 5 实现反向传播 6 示例 实现网络层的逻辑 首先实现一个简单的网络层 该网络层什么也不做 就是前向传播
  • Ubuntu指令之:统计指定类型文件的数目。eg:json、jpg

    ls grep 和 wc 命令统计指定类型文件数目的技巧 命令之间的交互通过命名管道完成 grep 用户根据给定模式或正则表达式进行搜索的命令 wc 用于统计行 字和字符的命令 1 普通文件的数目 用符号 表示 ls l grep wc l
  • ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out.解决方案

    刚刚下载python3第三方库 下载速度真的慢 而且下载超过时间就会报错 真的心态崩了 下面提供我找到的解决方案 解决方法 1 设置控制超时 pip install default timeout 1000 包的名称 2 更换pip下载源
  • 可以说说猿如意的基本功能以及作用是什么啊?

    猿如意是一款软件工具 它的基本功能是帮助用户编写 调试和执行 Python 代码 它可以作为一个集成开发环境 Integrated Development Environment IDE 来使用 也可以作为一个单独的代码编辑器使用 猿如意提
  • LaTeX - 设置中文字体

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 第一步 字体从电脑导出 Window R输入cmd回车 输入fc list f family n lang zh gt d zhfont txt 回车 enter键 可以用
  • 高斯噪声

    高斯噪声 图像噪声之高斯噪声 gauss noise 概述 高斯噪声是指它的概率密度函数服从高斯分布 即正态分布 的一类噪声 与椒盐噪声相似 Salt And Pepper Noise 高斯噪声 gauss noise 也是数字图像的一个常
  • 【正点原子MP157连载】第五章 ATK-STM32MP157文件系统简介-摘自【正点原子】STM32MP157快速体验

    第五章 ATK STM32MP157文件系统简介 5 1 文件系统目录简介 5 2 文件系统Qt版本 5 3 如何创建systemd 自启动服务 5 4 如何禁用Qt界面启动 1 实验平台 正点原子STM32MP157开发板 2 购买链接
  • 红帽文件系统满了服务器启动不了,红帽系统盘问题汇总解答.doc

    红帽系统盘问题汇总解答 PAGE PAGE 1 作者 日期 PAGE NUMPAGES 做题盘问题汇总 备注 必须64位的机子 问题1 视频里的那个开始的脚本 O号0根不分不清 答 没有零都是大写的O 问题2 那我打了零 CSR证书可能要重
  • eclipse下新建maven web工程(是web工程!)以及部署maven web工程到tomcat服务器

    一 eclipse新建maven web工程 1 在菜单栏File gt New下面找到Maven Project 2 勾选上Create a simple project 不使用骨架 Next 3 填写工程名称和包名 并选择war类型 一
  • 支持向量机SVM的学习

    20201102 0 引言 支持向量机作为一种常用的机器学习算法 应用非常广泛 原始的SVM只能支持线性数据 而通过核函数的方式 可以使其应用于非线性数据 之前学习过SVM的具体过程 也在sklearn中进行过调优 但是都没有记录 而且上次
  • 4.2 计算机体系结构——存储层次结构——cache工作原理

    cache是小容量 高速缓冲存储器 由SRAM组成 速度几乎和CPU一样快 一般将cache和主存的存储空间都划分为若干大小相同的块 1 cache工作原理 根据时间局部性和空间局部性 当处理器访问一块数据时 它很可能再次访问这块数据或者访
  • 【Spring AOP】Spring AOP快速使用

    文章目录 前言 1 相关注解 类注解 方法注解 2 execution 表达式 例一 execution 表达式 的限制使用 例二 execution 表达式 的通配使用 3 相关pom依赖 4 案例 创建接口 Aop使用 方式一 Befo