Spring07——AOP通知以及几个相关案例

news2025/1/4 20:28:26

切入点表达式 

注意,不是参数,是参数类型

可以使用通配符描述切入点,快速描述

■ *:单个独立的任意符号,可以独立出现,也可以作为前缀或者后缀的通配符出现

execution(public∗com.itheima.∗.UserService.find(∗))

匹配com.itheima包下的任意类中的UserService类接口中所有find开头的带有一个参数的方法

■ ... :多个连续的任意符号,可以独立出现,常用于简化包名与参数的书写

execution(publicUsercom..UserService.findById(..))

匹配com包下的任意包中的UserService类或接口中所有名为findById的方法

■ +:专用于匹配子类类型

execution(∗.∗.Service+..(∗..))

书写技巧

  1. 所有代码按照标准规范开发,否则以下技巧全部失效
  2. 描述切入点通常描述接口,而不描述实现类
  3. 访问控制修饰符对接口的开发采用public修饰
  4. 返回值类型对于增删改查类使用精确型匹配(可省略访问控制修饰符描述)
  5. 包含书签是尽量不使用..匹配,效率较低,常常做单个匹配或精确匹配
  6. 接口名称/类名名称与模块相关的最好采用..匹配,例如UserService书写为*Service,绑定业务层接口名称
  7. 方法名称书写以动词开头清晰匹配,例如采用..匹配,可以采用书写如getBy或.selectAll书写为selectAll
  8. 参数则较为复杂,根据具体方法灵活调整
  9. 通常不使用异常作为..匹配规则

AOP通知类型

@Around通知(用的最多)

@Pointcut("execution(* com.itheima.dao.BookDao.save())")
private void pointcut() {} // 切入点方法(save),具体实现为空
// 使用@Around注解定义一个环绕通知,用于在目标方法执行前后添加自定义逻辑  
@Around("pointcut()") // pointcut()是切入点表达式,指定在哪些方法上应用此通知  
public void way(ProceedingJoinPoint pjp) throws Throwable {  
    // 在目标方法执行前的逻辑  
    System.out.println("执行前");  
    
    // 执行目标方法  
    pjp.proceed(); // pjp.proceed()调用目标方法,允许原始方法继续执行  
    
    // 在目标方法执行后的逻辑  
    System.out.println("执行后");  
}

返回Int的@Around通知

// 定义一个切入点,匹配com.itheima.dao.BookDao类中的select()方法
@Around("execution(int com.itheima.dao.BookDao.select(int))")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        // 方法执行前的逻辑
        System.out.println("Before method: " + joinPoint.getSignature());

        // 调用目标方法并获取返回值
        Integer result = (Integer) joinPoint.proceed();

        // 方法执行后的逻辑
        System.out.println("After method: " + joinPoint.getSignature());
        System.out.println("Method returned: " + result);

        return result; // 返回目标方法的结果
    }

上面的定义切入点可以直接用@Around声明。

如果切点函数的返回值为int或其他类型,强转为Integer(在函数前面限定返回值为Object)那么接收再最后return

@AfterReturning:没有抛异常才会最后执行,可以访问方法的返回值。适合于记录成功操作的日志或修改返回结果。

@AfterThrowing:在目标方法抛出异常后执行通知,可以用于异常处理和错误记录。

案例:模拟测量运行10000次时间

@Around("execution(* com.itheima.mapper.UserMapper.SelectStudentById(int))") // 修改为匹配所有方法
    public void testtime(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis(); // 记录开始时间

        // 执行目标方法 10,000 次
        int iterations = 10000;
        for (int i = 0; i < iterations; i++) {
            // 调用目标方法并获取返回值
            joinPoint.proceed();
        }

        long endTime = System.currentTimeMillis(); // 记录结束时间
        long totalTime = endTime - startTime; // 计算总时间

        // 输出总时间
        System.out.println(joinPoint.getSignature() + "Total time for " + iterations + " executions: " + totalTime + " ms");

         // 或者返回某个结果
    }
@Test
    public void TestSelectStudentById(){
        User user = userMapper.SelectStudentById(2);
    }

AOP通知获取参数 

// 没有返回值的方法
@Before("pt()")
public void before(JoinPoint jp) {
Object[] args = jp.getArgs();
System.out.println(Arrays.toString(args));
}
// 有返回值的方法
@Around("pt()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Object[] args = pjp.getArgs();
System.out.println(Arrays.toString(args));
Object ret = pjp.proceed();
return ret;
}

抛出异常了解一下 

案例:百度网盘密码格式处理

 问题引入

@Around("DataAdvice.servicePt()")
public Object trimString(ProceedingJoinPoint pjp) throws Throwable {
    Object[] args = pjp.getArgs();
    // 对原始参数的每一个参数进行操作
    for (int i = 0; i < args.length; i++) {
        // 如果是字符串数据
        if (args[i].getClass().equals(String.class)) {
            // 取出数据,trim()操作后,更新数据
            args[i] = args[i].toString().trim();
        }
    }
    return pjp.proceed(args);
}

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

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

相关文章

【ETCD】【源码阅读】configurePeerListeners() 函数解析

configurePeerListeners 是 ETCD 的一个核心函数&#xff0c;用于为集群中节点之间的通信配置监听器&#xff08;Peer Listener&#xff09;。这些监听器主要负责 Raft 协议的消息传递、日志复制等功能。函数返回一个包含所有监听器的列表。 函数签名 func configurePeerList…

Kafka怎么发送JAVA对象并在消费者端解析出JAVA对象--示例

1、在pom.xml中加入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-stream-kafka</artifactId><version>3.1.6</version></dependency> 2、配置application.yml 加入Kafk…

为了安全,自己搭建KMS,成功激活Office2010

在本篇文章中&#xff0c;将全过程描述Office Professional Plus 2010 With SP1 VOL从下载到自建KMS服务器再到激活的过程。本文展示的是64位版本&#xff0c;32位版本的方法类似。 特别注意&#xff1a;KMS激活仅限于VOL 版本&#xff0c;其他的零售版无法激活&#xff01;&am…

Unity 基于Collider 组件在3D 物体表面放置3D 物体

实现 从鼠标点击的屏幕位置发送射线&#xff0c;以射线监测点击到的物体&#xff0c;根据点击物体的法线向量调整放置物体的位置及朝向。 Ray ray Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out RaycastHit hit, 100)) {obj.transform.…

【RDMA】RDMA read和write编程实例(verbs API)

WRITE|READ编程&#xff08;RDMA read and write with IB verbs&#xff09; &#xff08;本文讲解的示例代码在&#xff1a;RDMA read and write with IB verbs | The Geek in the Corner&#xff09; 将 RDMA 与verbs一起使用非常简单&#xff1a;首先注册内存块&#xff0c…

HTML5教程-表格宽度设置,最大宽度,自动宽度

HTML表格宽度 参考&#xff1a;html table width HTML表格是网页设计中常用的元素之一&#xff0c;可以用来展示数据、创建布局等。表格的宽度是一个重要的参数&#xff0c;可以通过不同的方式来设置表格的宽度&#xff0c;本文将详细介绍HTML表格宽度的不同设置方式和示例代…

2024年12月9日Github流行趋势

项目名称&#xff1a;ollama / ollama 项目维护者&#xff1a;mxyng, jmorganca, dhiltgen, BruceMacD, technovangelist等项目介绍&#xff1a;快速上手使用Llama 3.2、Mistral、Gemma 2及其他大型语言模型。项目star数&#xff1a;101,591项目fork数&#xff1a;8,117 项目名…

IntelliJ+SpringBoot项目实战(29)--如何将Beetl的模板文件放在独立的文件目录

在实际的项目开发中&#xff0c;为了方便前端人员调试页面&#xff0c;所以有必要将Beetl的模板文件放在独立的目录下&#xff0c;方便前端人员维护&#xff0c;而不是打包到项目的jar包中&#xff0c;如果打包到项目的jar包中还有另外的问题&#xff0c;就是一改动页面就要重新…

在Ubuntu上使用IntelliJ IDEA:开启你的Java开发之旅!

你好&#xff0c;年轻的学徒&#xff01;&#x1f9d1;‍&#x1f4bb; 是时候踏上进入Java开发世界的史诗之旅了&#xff0c;我们的得力助手将是强大的IntelliJ IDEA。准备好了吗&#xff1f;出发吧&#xff01; 在我们开始之前&#xff0c;我们需要下载这个工具。但是&#…

GWAS分析先做后学

大家好&#xff0c;我是邓飞。 GWAS分析是生物信息和统计学的交叉学科&#xff0c;上可以学习编程&#xff0c;下可以学习统计。对于Linux系统&#xff0c;R语言&#xff0c;作图&#xff0c;统计学&#xff0c;机器学习等方向&#xff0c;都是一个极好的入门项目。生物信息如…

LeetCode—189. 轮转数组(中等)

题目描述&#xff1a; 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例1&#xff1a; 输入: nums [1,2,3,4,5,6,7], k 3输出:[5,6,7,1,2,3,4] 解释: 向右轮转 1 步:[7,1,2,3,4,5,6] 向右轮转 2 步:[6,7,1,2,3,4,5] 向…

ModelScope-Agent(1): 基于开源大语言模型的可定制Agent系统

目录 简介快速入门 简介 github地址 快速入门 看前两篇&#xff0c;调用千问API和天气API # 选用RolePlay 配置agent from modelscope_agent.agents.role_play import RolePlay # NOQArole_template 你扮演一个天气预报助手&#xff0c;你需要查询相应地区的天气&#x…

go语言的成神之路-标准库篇-fmt标准库

目录 一、三种类型的输出 print&#xff1a; println&#xff1a; printf&#xff1a; 总结&#xff1a; 代码展示&#xff1a; 二、格式化占位符 %s&#xff1a;用于格式化字符串。 %d&#xff1a;用于格式化整数。 %f&#xff1a;用于格式化浮点数。 %v&#xff1…

pyenv 安装脚本解读

pyenv 安装脚本 curl https://pyenv.run | bash执行上面这一行脚本就可以安装pyenv来满足你对 Python 多版本共存以及切换的支持。 pyenv搭配virtualenv可以满足你对Python虚拟环境版本的支持。个人感觉pyenv比conda更轻量&#xff0c;更推荐使用。 那么上面的脚本到底干了什…

OpenAI 12Days 第二天 强化微调(RFT):推动语言模型在科学研究中的应用

OpenAI 12Days 第二天 强化微调&#xff08;RFT&#xff09;&#xff1a;推动语言模型在科学研究中的应用 文章目录 OpenAI 12Days 第二天 强化微调&#xff08;RFT&#xff09;&#xff1a;推动语言模型在科学研究中的应用RFT的工作原理与应用领域案例研究&#xff1a;基因突变…

柯桥职场商务英语生活英语口语培训外贸纺织口语学习

"等一下"该怎么说&#xff1f; 大家应该都知道&#xff0c;wait a moment是一个祈使句&#xff0c;祈使句就难免带有命令的口吻&#xff0c;还有点不耐烦。 如果你把“等一下”说成wait a moment&#xff0c;外国人多半认为你是个傲慢无礼的人。毕竟在他们看来wait a…

嵌入式蓝桥杯学习7 产生PWM

Cubemx配置 打开cubemx&#xff0c;前面的配置看上文&#xff0c;这里主要配置定时器产生PWM波。 以PA1的TIM2-CH2通道为例进行演示。 1.在Timers中打开TIM2,将Channel2配置为PWM Generation CH2。 2.将Clock Source 选择为Internal Clock。 3.配置Paramater Settings中的参…

SQL Server中SELECT (Transact-SQL)语法定义和解释

语法定义&#xff1a; <SELECT statement> ::[ WITH { [ XMLNAMESPACES , ] [ <common_table_expression> [ , ...n ] ] } ]<query_expression>[ ORDER BY <order_by_expression> ][ <FOR Clause> ][ OPTION ( <query_hint> [ , ...n ] )…

证书监控续签工具

详细实现方式以及代码下载请前往https://www.passerma.com/article/91 一个基于 go 的 ssl 证书监控续签工具&#xff0c;用于监控阿里云免费 ssl 证书的有效期&#xff0c;并在证书即将过期时自动续签证书 仅支持续签阿里云的免费证书 页面 使用方法 1.申请阿里云账号 2.…

【开源】A063—基于Spring Boot的农产品直卖平台的设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看项目链接获取⬇️&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600个选题ex…