Spring面向切面编程AOP(2)

前置通知(Before Advice)

前置通知在目标方法执行之前被调用,常用于执行一些预处理逻辑,例如权限验证、参数校验等。在 Spring 配置文件中,前置通知通过<aop:before>标签进行配置,以下是一个典型的示例:

<aop:before method="yanzheng" pointcut="execution(public void com.qcby.Demo.search(..))"/>

上述配置中,method="yanzheng"指定了通知方法,即当满足pointcut定义的切入点条件时,会执行yanzheng方法。pointcut属性用于定义切入点表达式,execution(public void com.qcby.Demo.search(..))表示当com.qcby.Demo类中的search方法被调用时,触发前置通知。

最终通知(After Advice)

最终通知在目标方法执行之后被调用,无论目标方法是正常返回还是抛出异常,该通知都会执行。这种通知类型适用于资源清理、状态更新等场景。在 Spring 配置文件中,通过<aop:after>标签配置最终通知:

<aop:after method="yanzheng" pointcut="execution(public void com.qcby.Demo.search(..))"/>

即使search方法执行过程中出现异常,yanzheng方法也会被执行,确保后续的清理或记录操作能

够顺利完成。

异常通知(After-Throwing Advice)

异常通知仅在目标方法抛出异常时被调用,它允许我们在异常发生时进行特定的处理,如记录异常日志、回滚事务等。通过<aop:after-throwing>标签配置异常通知:

<aop:after-throwing method="yanzheng" pointcut="execution(public void com.qcby.Demo.search(..))"/>

search方法抛出异常,yanzheng方法会捕获异常并执行相应的处理逻辑,帮助开发者更好地管理程序运行过程中的错误情况。

后置通知(After-Returning Advice)

后置通知在目标方法正常执行完毕且返回结果后被调用,可用于记录方法执行结果、更新缓存等操作。通过<aop:after-returning>标签配置后置通知:

<aop:after-returning method="yanzheng" pointcut="execution(public void com.qcby.Demo.search(..))"/>

只有search方法成功执行并返回,yanzheng方法才会被触发,如果方法执行过程中抛出异常,后置通知不会执行。

环绕通知(Around Advice)

环绕通知是功能最强大的通知类型,它可以在目标方法执行之前和之后都执行自定义逻辑,甚至可以决定是否执行目标方法。环绕通知通过<aop:around>标签进行配置:

<aop:around method="yanzheng" pointcut="execution(public void com.qcby.Demo.search(..))"/>

在环绕通知的方法中,开发者可以使用ProceedingJoinPoint参数来调用目标方法,实现更加灵活的逻辑控制。例如,在性能监控场景中,可以在目标方法执行前记录开始时间,执行后记录结束时间并计算执行耗时。

package com.qcby;import org.aspectj.lang.ProceedingJoinPoint;public class DemoProxy {public void yanzheng(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("对name和age进行验证.....执行之前");
//        执行切入点proceedingJoinPoint.proceed();System.out.println("对name和age进行验证.....执行之后");}}

 

注解式 AOP 基础配置

要使用注解方式配置 AOP,首先需要确保以下几点:

  1. 在 Spring 配置文件中启用 AOP 自动代理:
<aop:aspectj-autoproxy/>
  1. 创建切面类并使用@Aspect注解标记
  2. 将切面类声明为 Spring Bean(使用@Component@Controller等注解)

下面是一个典型的注解式切面类示例:

package com.qcby;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Controller;@Controller
@Aspect
public class DemoProxy {// 通知方法实现
}

各种通知类型的注解实现

环绕通知(@Around)

环绕通知是功能最强大的通知类型,它允许在目标方法执行前后都添加自定义逻辑。在DemoProxy类中,环绕通知的实现如下:

@Around(value = "execution(public void com.qcby.Demo.search(..))")
public void yanzheng(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("对name和age进行验证.....执行之前");// 调用目标方法proceedingJoinPoint.proceed();System.out.println("对name和age进行验证.....执行之后");
}

关键点解析:

  • @Around注解指定了通知类型和切入点表达式
  • ProceedingJoinPoint参数用于控制目标方法的执行
  • proceed()方法调用目标方法,可以在调用前后添加自定义逻辑

 

前置通知(@Before)

前置通知在目标方法执行前被调用:

@Before(value = "execution(public void com.qcby.Demo.search(..))")
public void yanzheng() {System.out.println("对name和age进行验证!!");
}

 

后置通知(@After)

后置通知在目标方法执行后被调用,无论方法是否抛出异常:

@After(value = "execution(public void com.qcby.Demo.search(..))")
public void yanzheng() {System.out.println("后置通知执行");
}

 

异常通知(@AfterThrowing)

异常通知仅在目标方法抛出异常时被调用:

@AfterThrowing(value = "execution(public void com.qcby.Demo.search(..))")
public void yanzheng() {System.out.println("异常通知执行");
}
    //在查询之前验证name和agepublic void search(String name,int age){Integer a=10/0;System.out.println("search.................");}}

 

返回通知(@AfterReturning)

返回通知在目标方法正常返回后被调用:

@AfterReturning(value = "execution(public void com.qcby.Demo.search(..))")
public void yanzheng() {System.out.println("返回通知执行");
}

 

注解式 AOP 的优势

与 XML 配置方式相比,注解式 AOP 具有以下优势:

  1. 代码更简洁:无需编写大量 XML 配置,所有 AOP 逻辑集中在切面类中
  2. 可读性更强:通知类型和切入点表达式直接与通知方法关联
  3. 维护更方便:AOP 逻辑与切面类代码放在一起,便于修改和管理
  4. 类型安全:编译时就能检查切入点表达式的正确性

 

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

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

相关文章

设备故障预测与健康管理技术:从数据到决策的工业智能进化之路​

在工业 4.0 与智能制造浪潮的推动下&#xff0c;设备故障预测与健康管理&#xff08;Prognostics and Health Management, PHM&#xff09;技术已成为企业实现数字化转型的核心驱动力。据统计&#xff0c;制造业中设备非计划停机 1 小时的平均损失高达 25 万美元&#xff0c;而…

RabbitMQ从入门到实践:消息队列核心原理与典型应用场景

在现代应用开发中&#xff0c;系统各部分之间的通信至关重要。这就是像RabbitMQ这样的消息代理发挥作用的地方。无论您是在构建微服务架构、实现任务队列&#xff0c;还是开发实时聊天应用程序&#xff0c;RabbitMQ都可能成为改变游戏规则的工具。本文将深入探讨RabbitMQ是什么…

基于Spring Boot和Vue的网上军事论坛设计与实现

目录 一.&#x1f981;前言二.&#x1f981;开源代码与组件使用情况说明三.&#x1f981;核心功能1. ✅算法设计2. ✅Java开发语言3. ✅Redis数据库4. ✅部署项目 四.&#x1f981;演示效果1. 管理员模块1.1 用户管理1.2 内容审核1.3 权限分配1.4 菜单管理1.5 字典管理 2. 用户…

LLMs基础学习(八)强化学习专题(6)

LLMs基础学习&#xff08;八&#xff09;强化学习专题&#xff08;6&#xff09; 文章目录 LLMs基础学习&#xff08;八&#xff09;强化学习专题&#xff08;6&#xff09;深度强化学习&#xff08;DQN&#xff09;DQN 起源&#xff1a;《Playing Atari with Deep Reinforceme…

JVM(10)——详解Parallel垃圾回收器

Parallel 垃圾回收器&#xff08;也称为 吞吐量优先收集器&#xff09;。它是 Java 早期&#xff08;特别是 JDK 8 及之前&#xff09;在多核处理器上的默认垃圾回收器&#xff0c;其核心设计目标是最大化应用程序的吞吐量。 一、Parallel 回收器的定位与设计目标 核心目标&am…

MySQL(91)什么是分布式数据库?

分布式数据库是一种将数据存储在多个物理位置的数据库系统。这些位置可能分布在不同的服务器、数据中心甚至地理位置。分布式数据库系统允许数据的存储、处理和访问分布在多个节点上&#xff0c;以提高数据的可用性、可靠性、可扩展性和性能。 1. 分布式数据库的特点 1.1 数据…

Java事务失效(面试题)的常见场景

1. 方法非public修饰 原理&#xff1a; Spring AOP代理&#xff08;CGLIB或JDK动态代理&#xff09;默认无法拦截非public方法。 示例&#xff1a; Service public class UserService {Transactionalvoid updateUser() { // 非public方法// 事务不会生效&#xff01;} } 修…

GitHub 趋势日报 (2025年06月20日)

&#x1f4ca; 由 TrendForge 系统生成* | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 1810 data-engineer-handbook 373 n8n 295 anthropic-cookbook 291 automatisch…

qt常用控件--01

文章目录 qt常用控件--01上一篇文章的补充windowTitle属性windowIcon属性windowOpaCity属性cursor属性font属性结语 很高兴和大家见面&#xff0c;给生活加点impetus&#xff01;&#xff01;开启今天的编程之路&#xff01;&#xff01; 今天我们进一步c11中常见的新增表达 作…

C++ 中 string 类的解析及简易自我实现

目录 引言 标准库中的 string 类 功能概述 常见操作示例 自我实现简易 string 类 代码结构概述 1. String11.h 头文件 类的成员变量 迭代器相关 构造函数和析构函数 基本访问和修改方法 赋值运算符重载 内存管理和扩容 以下代码在.cpp文件中解析: 2. String11.…

计算机的性能指标(选择题0~1题无大题)

存储器的性能指标 总容量存储单元个数*存储字长 bit 例&#xff1a;MAR16位&#xff0c;MDR16位 总容量2的16次方*16bit 补充&#xff1a; n个二进制位就有2的n次方不同的状态 一般描述文件大小容量单位 2的10次方&#xff1a;K 2的20次方&#xff1a;M 2的…

React 核心原理与Fiber架构

目录 一、虚拟 DOM 二、Diffing 算法 三、Fiber 架构 四、渲染流程 1. Render 阶段&#xff08;可中断异步过程&#xff09; 2. Commit 阶段&#xff08;同步不可中断&#xff09; 五、时间切片&#xff08;Time Slicing&#xff09; 六、核心流程步骤总结 1. 状态更新…

【破局痛点,赋能未来】领码 SPARK:铸就企业业务永续进化的智慧引擎—— 深度剖析持续演进之道,引领数字化新范式

摘要 在瞬息万变的数字时代&#xff0c;企业对业务连续性、敏捷创新及高效运营的需求日益迫切。领码 SPARK 融合平台&#xff0c;秉持“持续演进”这一核心理念&#xff0c;以 iPaaS 与 aPaaS 为双擎驱动&#xff0c;深度融合元数据驱动、智能端口调度、自动化灰度切换、AI 智…

掌握C++核心特性

目标&#xff1a; 掌握C核心特性&#xff0c;为嵌入式开发打基础 好的&#xff0c;我来为你详细梳理一下 继承与多态、虚函数 相关的知识点&#xff0c;包括单继承、多继承、虚函数表机制、纯虚函数与抽象类、动态绑定。以下内容适合中等难度层次的理解&#xff0c;便于考试复…

python的高校教师资源管理系统

目录 技术栈介绍具体实现截图系统设计研究方法&#xff1a;设计步骤设计流程核心代码部分展示研究方法详细视频演示试验方案论文大纲源码获取/详细视频演示 技术栈介绍 Django-SpringBoot-php-Node.js-flask 本课题的研究方法和研究步骤基本合理&#xff0c;难度适中&#xf…

Java Collections工具类:高效集合操作

Collections工具类概述 Collections是Java提供的集合操作工具类&#xff0c;位于java.util包中&#xff0c;包含大量静态方法&#xff0c;用于对List、Set、Map等集合进行排序、查找、替换、同步化等操作。 常用方法及代码示例 排序操作 sort(List<T> list)&#xff1a…

vue指令总结

vue指令总结 一、总述 二、代码实现&#xff08;内含大量注释&#xff09; <!DOCTYPE html> <html> <head><meta charset"utf-8"><title>vue入门</title><!-- 使用Vue 3官方CDN --><script src"https://unpkg.c…

RUP——统一软件开发过程

RUP概述 RUP&#xff08;Rational Unified Process&#xff09;&#xff0c;统一软件开发过程&#xff0c;统一软件过程是一个面向对象且基于网络的程序开发方法论。 在RUP中采用“41”视图模型来描述软件系统的体系结构。“41”视图包括逻辑视图、实现视图、进程视图、部署视…

SpringBoot电脑商城项目--增加减少购物车商品数量

1. 持久层 1.1 规划sql语句 执行更新t_cart表记录的num值根据cid查询购物车的数据是否存在 select * from t_cart where cid#{cid} 1.2 接口和抽象方法 /*** 获取购物车中商品的数据总数* return 购物车中商品的数据总数*/Cart findByCid(Integer cid); 1.3 xml文件中sql映射…

零基础学习Redis(13) -- Java使用Redis命令

上期我们学习了如何使用Java连接到redis&#xff0c;这期我们来学习如何在java中使用redis中的一些命令 1. set/get 可以看到jedis类中提供了很多set方法 public static void test1(Jedis jedis) {jedis.flushAll();jedis.set("key1", "v1");jedis.set(&q…