【springboot】使用AOP

news2024/12/25 9:03:47

目录

  • 1. 添加依赖
  • 2. 创建切面类
    • 1. 创建切面类
    • 2. 切点表达式
    • 3. 增强方法
  • 3. 开启AOP
  • 4. 创建控制类
  • 5. 测试

1. 添加依赖

<!--        AOP依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

2. 创建切面类

1. 创建切面类

      创建一个切面类,并使用 @Aspect 注解标记,并在这个类中定义切点和通知。

@Aspect // 表示这是一个切面
@Component // 托管到spring容器中
public class AccessRecordAspect {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    // 定义切点 匹配TestController中的test*方法
    @Pointcut("execution(* com.huan.web.controllers.TestController.test*(..))")
    public void a(){}

    // 使用后置增强,在方法正确执行后执行
    @AfterReturning("a()")
    public void record(JoinPoint joinPoint){
        System.out.println("记录访问记录");
        // 获取目标方法参数
        Object[] args = joinPoint.getArgs();
        System.out.println(args[0]);
    }
}

2. 切点表达式

      切点表达式通用模式:execution(修饰符模式? 返回类型模式 包名.类名.方法名(参数模式) 异常模式?)
      其中的 ? 表示该部分是可选的

  • 修饰符模式:可选部分,用于匹配方法的修饰符(如 public、private 等)。例如:public。
  • 返回类型模式:用于匹配方法的返回类型。可以使用通配符 * 表示任意返回类型。例如:*。
  • 包名:用于匹配方法所在的包名。例如:com.example.service。
  • 类名:用于匹配方法所在的类名。可以使用通配符 * 表示任意类。例如:*。
  • 方法名:用于匹配方法名。可以使用通配符 * 表示任意方法。例如:*。
  • 参数模式:用于匹配方法的参数类型。可以使用通配符 … 表示任意数量和类型的参数。例如:(…)。
  • 异常模式:可选部分,用于匹配方法抛出的异常类型。例如:throws IOException。

一些常见的切点表达式示例:

execution:
    用于匹配方法执行。
    语法:execution(修饰符模式? 返回类型模式 包名.类名.方法名(参数模式) 异常模式?)
    示例:execution(* com.example.service.*.*(..)) 匹配 com.example.service 包中的所有类的所有方法。

within:
    用于匹配指定类型内的方法。
    语法:within(type-pattern)
    示例:within(com.example.service..*) 匹配 com.example.service 包及其子包中的所有类。

this:
    用于匹配当前 AOP 代理对象的类型。
    语法:this(type)
    示例:this(com.example.service.UserService) 匹配代理对象是 UserService 类型的所有方法。

target:
    用于匹配目标对象的类型。
    语法:target(type)
    示例:target(com.example.service.UserService) 匹配目标对象是 UserService 类型的所有方法。

args:
    用于匹配方法参数的类型。
    语法:args(argument-type-pattern)
    示例:args(java.lang.String) 匹配所有参数为 String 类型的方法。

@annotation:
    用于匹配方法上具有指定注解的方法。
    语法:@annotation(annotation-type)
    示例:@annotation(org.springframework.transaction.annotation.Transactional) 匹配所有带有 @Transactional 注解的方法。

@within:
    用于匹配具有指定注解的类型内的方法。
    语法:@within(annotation-type)
    示例:@within(org.springframework.stereotype.Service) 匹配所有带有 @Service 注解的类中的方法。

@target:
    用于匹配目标对象类型上具有指定注解的方法。
    语法:@target(annotation-type)
    示例:@target(org.springframework.stereotype.Service) 匹配目标对象类型上带有 @Service 注解的方法。

@args:
    用于匹配运行时传递的参数具有指定注解的方法。
    语法:@args(annotation-type)
    示例:@args(org.springframework.web.bind.annotation.RequestBody) 匹配参数带有 @RequestBody 注解的方法。

3. 增强方法

  • @Before:在目标方法执行前执行。
  • @After:在目标方法执行后执行。
  • @AfterReturning:在目标方法正常返回后执行。
  • @AfterThrowing:在目标方法抛出异常后执行。
  • @Around:环绕增强,可以在目标方法执行前后执行。

      我之前简单测试了下五种增强方法的执行顺序(文章),结论如下:

  • 无异常时  执行顺序为:环绕增强(前)-> 前置增强 -> 目标方法 -> 返回增强 -> 后置增强 -> 环绕增强(后)
  • 有异常时  执行顺序为:环绕增强(前)-> 前置增强 -> 目标方法 -> 异常增强 -> 后置增强 。

3. 开启AOP

      在配置文件中使用@EnableAspectJAutoProxy注解开启AOP功能

在这里插入图片描述

4. 创建控制类

@RestController
@RequestMapping("test")
@Tag(name = "测试",description = "测试springMVC拦截器实现记录访问次数")
public class TestController {
    @GetMapping("getInfo/{id}")
    public String test(@PathVariable Integer id) {
        switch (id){
            case 1:
                return "1";
            case 2:
                return "2";
            default:
                return "3";
        }
    }
}

5. 测试

      在浏览器中输入 http://localhost:8080/test/getInfo/1 测试aop是否生效。
在这里插入图片描述
      console输出,AOP生效。

在这里插入图片描述
      over…
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2116640.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【iOS】MVC入门

【iOS】MVC模式的学习 文章目录 【iOS】MVC模式的学习前言MVC模式概念MVC的交流模式MVC的一个简单实践Model层View层Controller层 MVC的优点与缺点总结 前言 笔者在暑假的学习中完成了一些小项目&#xff0c;这些小项目中间有时候出现了一个小bug都要寻找很久&#xff0c;而且会…

前端学习笔记-Web APls篇-05

Bom操作 1.Window对象 1.1BOM(浏览器对象模型&#xff09; BOM(Browser Object Model ) 是浏览器对象模型 window对象是一个全局对象&#xff0c;也可以说是JavaScript中的顶级对象像document、alert()、console.log()这些都是window的属性&#xff0c;基本BOM的属性和方法都…

SAM2POINT:以zero-shot且快速的方式将任何 3D 视频分割为视频

摘要 我们介绍 SAM2POINT&#xff0c;这是一种采用 Segment Anything Model 2 (SAM 2) 进行零样本和快速 3D 分割的初步探索。 SAM2POINT 将任何 3D 数据解释为一系列多向视频&#xff0c;并利用 SAM 2 进行 3D 空间分割&#xff0c;无需进一步训练或 2D-3D 投影。 我们的框架…

ML19_GMM高斯混合模型详解

1. 中心极限定理 中心极限定理&#xff08;Central Limit Theorem, CLT&#xff09;是概率论中的一个重要定理&#xff0c;它描述了在一定条件下&#xff0c;独立同分布的随机变量序列的标准化和的分布趋向于正态分布的性质。这个定理在统计学中有着广泛的应用&#xff0c;尤其…

算法篇_C语言实现霍夫曼编码算法

一、前言 霍夫曼编码&#xff08;Huffman Coding&#xff09;是一种广泛使用的数据压缩算法&#xff0c;特别适用于无损数据压缩。它是由David A. Huffman在1952年提出的&#xff0c;并且通常用于文件压缩和传输中减少数据量。霍夫曼编码的核心思想是使用变长编码表对源数据进…

提升效率必备!学习awk命令,轻松搞定数据

在日常的工作中&#xff0c;无论是数据处理、日志分析&#xff0c;还是格式化输出&#xff0c;AWK命令都是不可或缺的利器。AWK是一种强大的文本处理工具&#xff0c;能让你轻松处理复杂的数据&#xff0c;提升工作效率。本文将为你介绍AWK的基本功能及一些实用场景&#xff0c…

树 --- 二叉树

树的物理结构和逻辑结构上都是树形结构。 树形结构&#xff1a;由一个根和若干个子节点组成的集合。 最外围的为叶子节点&#xff1a;只有前驱而没有后继。 &#xff08;一&#xff09;树的性质 • ⼦树是不相交的 • 除了根结点外&#xff0c;每个结点有且仅有⼀个⽗结点 •…

每天五分钟玩转深度学习框架PyTorch:将nn的神经网络层连接起来

本文重点 前面我们学习pytorch中已经封装好的神经网络层,有全连接层,激活层,卷积层等等,我们可以直接使用。 如代码所示我们直接使用了两个nn.Linear(),这两个linear之间并没有组合在一起,所以forward的之后,分别调用了,在实际使用中我们常常将几个神经层组合在一起…

【EI会议征稿通知】第十一届机械工程、材料和自动化技术国际会议(MMEAT 2025)

第十一届机械工程、材料和自动化技术国际会议&#xff08;MMEAT 2025&#xff09; 2025 11th International Conference on Mechanical Engineering, Materials and Automation Technology 本次大会旨在汇聚全球机械工程、材料科学及自动化技术的创新学者和行业专家&#xff0…

使用 BentoML快速实现Llama-3推理服务

介绍 近年来&#xff0c;开源大模型如雨后春笋般涌现&#xff0c;为自然语言处理领域带来了革命性的变化。从文本生成到代码编写&#xff0c;从机器翻译到问答系统&#xff0c;开源大模型展现出惊人的能力&#xff0c;吸引了越来越多的开发者和企业投身其中。 然而&#xff0…

Subclass-balancing Contrastive Learning for Long-tailed Recognition

文章目录 SCL(supervised contrastive learning)1. 监督对比学习&#xff08;SCL&#xff09;的基本概念2. SCL的损失函数3. 长尾数据集的问题4. k-正样本对比学习&#xff08;KCL&#xff09;的引入5. 总结 SBCL举例说明&#xff1a;狗的分类 关键点&#xff1a;划分为多个子类…

4-1.Android Camera 之 CameraInfo 编码模板(前后置摄像头理解、摄像头图像的自然方向理解)

一、Camera.CameraInfo Camera.CameraInfo 是用于获取设备上摄像头信息的一个类&#xff0c;它提供摄像头的各种详细信息&#xff0c;例如&#xff0c;摄像头的方向、是否支持闪光灯等&#xff0c;以下是它的常用属性 static int CAMERA_FACING_BACK&#xff1a;表示设备的后置…

Protobuf库的使用

文章目录 Protobuf是什么Protobuf使⽤流程介绍ProtoBuf的使用创建.proto⽂件指定proto3语法package声明符定义消息&#xff08;message&#xff09;编译contacts.proto⽂件命令如下&#xff1a;序列化与反序列化的使⽤ Protobuf是什么 ProtoBuf&#xff08;全称ProtocolBuffer…

数字 FPV 革命 – DJI、Leadcore 和 Artosyn 的三角关系。

人们对 DJI、Caddx FPV 以及 HDZero 等公司最近推出的数字 FPV 系统的起源进行了大量的猜测和推测。随着 Avatar 系统的发布&#xff0c;也有许多人认为它要么使用与 DJI 相同的芯片组&#xff0c;要么是复制品或克隆品。在本文中&#xff0c;我将尝试揭开这一切的神秘面纱&…

python spider novel

python msedgedriver 获取小说 声明&#xff1a;只为学习/练习技术 from lxml import etree from selenium import webdriver from selenium.webdriver.edge.service import Service from selenium.webdriver.edge.options import Optionsimport time# 初始化EdgeOptions, 以…

【系统规划与管理师】【案例分析】【考点】【答案篇】第4章 IT服务规划设计

【问题篇】☞【系统规划与管理师】【案例分析】【考点】【问题篇】第4章 IT服务规划设计 【移动端浏览】☞【系统规划与管理师】【案例分析】【模拟考题】章节考题汇总&#xff08;第4章&#xff09;&#xff08;答案篇&#xff09;&#xff08;共38个知识点&#xff09; 第4章…

《数字信号处理》学习05-单位冲击响应与系统响应

目录 一&#xff0c;单位冲激响应 二&#xff0c;LTI系统对任意序列的系统响应 三&#xff0c;LTI系统的性质 通过上一篇文章《数字信号处理》学习04-离散时间系统中的线性时不变系统-CSDN博客的学习&#xff0c;我已经知道了离散时间线性时不变系统&#xff08;LTI&#x…

基于 jenkins 的持续测试方案

CI/CD Continuous Integration; Continuous Deployment; 持续集成&#xff0c;将新代码和旧代码一起打包、构建&#xff1b;持续部署&#xff0c;将新构建的包进行部署&#xff1b;持续测试&#xff0c;将新代码、新单元测试一起测试&#xff1b;方案&#xff1a; 公有云DevO…

Python 控制Chrome浏览器使用Selenium4操作点击百度搜索

前面我们讲到如何安装Selenium和ChromeDriver来驱动打开网页,现在我们有一个目的就是使用python来控制chrome浏览器打开百度并搜索 直接先上调试好的代码 from time import sleepfrom selenium import webdriver from selenium.webdriver.common.keys import Keys from selen…

2-88 基于matlab的四叉树加权聚焦多聚焦图像融合

基于matlab的四叉树加权聚焦多聚焦图像融合&#xff0c;的四叉树分解策略将源图像被分解成四叉树结构中具有最佳尺寸的块。在这个树形结构中&#xff0c;使用一种新的加权焦点测量方法&#xff08;名为加权修正拉普拉斯之和&#xff09;来检测焦点区域。可以很好地从源图像中提…