news 2026/5/14 17:09:47

Spring AOP概念

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring AOP概念

Spring AOP是什么?

Spring AOP是面向切面编程,他与OOP(面向对象编程)是相辅相成的。

在 OOP 中,以类作为程序的基本单元,而 AOP 中的基本单元是 Aspect(切面)。

在业务处理代码中,通常都有日志记录、性能统计、安全控制、事务处理、异常处理等操作。尽管使用 OOP 可以通过封装或继承的方式达到代码的重用,但仍然存在同样的代码分散到各个方法中。因此,采用 OOP 处理日志记录等操作,不仅增加了开发者的工作量,而且提高了升级维护的困难。为了解决此类问题,AOP 思想应运而生。AOP 采取横向抽取机制,即将分散在各个方法中的重复代码提取出来,然后在程序编译或运行阶段,再将这些抽取出来的代码应用到需要执行的地方。这种横向抽取机制采用传统的 OOP 是无法办到的,因为 OOP 实现的是父子关系的纵向重用。但是AOP 不是 OOP 的替代品,而是 OOP 的补充,它们是相辅相成的。

Spring通知类型

环绕通知

环绕通知是在目标方法执行前和执行后实施增强,可以应用于日志记录、事务处理等。

前置通知

前置通知是在目标方法执行前实施增强,可应用于权限管理等。

后置返回通知

后置返回通知是在目标方法成功执行后实施增强,可应用于关闭流、删除临时文件等。

后置(最终)通知

后置通知是在目标方法执行后实施增强,与后置返回通知不同的是,不管是否发生异常都要执行该通知,可应用于释放资源。

异常通知

异常通知是在方法抛出异常后实施增强,可以应用于异常处理、日志记录等。

引入通知

引入通知是在目标类中添加一些新的方法和属性,可以应用于修改目标类(增强类)。

举例

使用 Eclipse 创建一个名为 Myaspect 的 Dynamic Web Project,必要的 jar 已经复制到 WEB-INF/lib 目录中。在 src 目录中,创建一个名为 aspectj.dao 的包,并在该包中创建接口 catDao 和接口实现类 catDaoImpl。该实现类作为目标类,在切面类中对其所有方法进行增强处理。

package aspectj.dao; public interface catDao { public void eat(); public void sleep(); public void play(); } package aspectj.dao; import org.springframework.stereotype.Repository; @Repository("catDao") public class catDaoImp implements catDao { @Override public void eat() { System.out.println("小猫吃饭"); } @Override public void sleep() { System.out.println("小猫睡觉"); } @Override public void play() { System.out.println("小猫玩"); } }

在 src 目录中,创建一个名为 aspectj.annotation 的包,并在该包中创建切面类 MyAspect。在该类中,用 @Aspect 注解定义一个切面类,并通过定义方法表示切入点名称。在目标类每一个方法上,做切面,成消息和目标方法名称输出,完成方式和消息为:

前置通知:主人召唤小猫

后置通知:小猫自主活动

环绕开始:执行目标方法前,开启摄像头

环绕结束:执行目标方法后,关闭摄像头

/** * 切面类,在此类中编写各种类型通知 */ @Aspect //@Aspect 声明一个切面 @Component //@Component 让此切面成为 Spring 容器管理的 Bean public class MyAspect { /** * 定义切入点,通知增强哪些方法。 * "execution(* aspectj.dao.*.*(..))" 是定义切入点表达式, * 该切入点表达式的意思是匹配aspectj.dao包中任意的任意方法的执行。 * 其中execution()是表达式的主体,第一个*表示返回类型,*代表所有类型; * aspectj.dao表示需要匹配的包名,后面第二个*表示类名,使用*代表匹配包中所有的类; * 第三个*表示方法名,使用*表示所有方法;后面(..)表示方法的参数,其中“..”表示任意参数。 * 另外,注意第一个*与包名之间有一个空格。 */ @Pointcut("execution(* aspectj.dao.*.*(..))") private void myPointCut() { } /** * 前置通知,使用 Joinpoint 接口作为参数获得目标对象信息 */ @Before("myPointCut()") //myPointCut()是切入点的定义方法 public void before(JoinPoint jp) { System.out.print("前置通知:主人召唤小猫"); System.out.println(",目标类对象:" + jp.getTarget() + ",被增强处理的方法:" + jp.getSignature().getName()); } /** * 后置返回通知 */ @AfterReturning("myPointCut()") public void afterReturning(JoinPoint jp) { System.out.print("后置返回通知:" + "小猫自主活动"); System.out.println(",被增强处理的方法:" + jp.getSignature().getName()); } /** * 环绕通知 * ProceedingJoinPoint 是 JoinPoint 子接口,代表可以执行的目标方法 * 返回值类型必须是 Object * 必须有一个参数是 ProceedingJoinPoint 类型 * 必须是 throws Throwable */ @Around("myPointCut()") public Object around(ProceedingJoinPoint pjp) throws Throwable { //开始 System.out.println("环绕开始:执行目标方法前,开启摄像头"); //执行当前目标方法 Object obj = pjp.proceed(); //结束 System.out.println("环绕结束:执行目标方法后,关闭摄像头"); return obj; } /** * 异常通知 */ @AfterThrowing(value = "myPointCut()", throwing = "e") public void except(Throwable e) { System.out.println("异常通知:" + "程序执行异常" + e.getMessage()); } /** * 后置(最终)通知 */ @After("myPointCut()") public void after() { System.out.println("最终通知:模拟释放资源"); } }

此处要着重会使用Joinpoint接口作为参数获取目标对象信息

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/10 19:26:02

Dify平台API权限控制机制的设计与实施

Dify平台API权限控制机制的设计与实施 在AI应用快速渗透企业核心业务的今天,一个看似不起眼的技术细节——API能不能被随意调用——往往决定了整个系统的安危。设想一下:某天你发现外部合作伙伴通过一个公开的接口,不仅调用了你的智能客服模型…

作者头像 李华
网站建设 2026/5/10 13:39:40

LobeChat能否实现多人协同编辑?共享会话功能设想

LobeChat能否实现多人协同编辑?共享会话功能设想 在远程办公常态化、AI助手深度融入工作流的今天,一个看似简单却日益凸显的问题浮出水面:我们能否像协作编辑一份文档那样,多人实时共用同一个AI对话? 想象这样一个场…

作者头像 李华
网站建设 2026/5/11 18:06:11

基于单片机的智能温控风扇系统设计(温度+风速调节)【附代码】

📈 算法与建模 | 专注PLC、单片机毕业设计 ✨ 擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导,毕业论文、期刊论文经验交流。✅ 专业定制毕业设计✅ 具体问题可以私信或查看文章底部二维码本系统的核心设计内容在于构建一个以单片机…

作者头像 李华
网站建设 2026/5/11 17:08:02

Python中配置TensorFlow-GPU的完整方法

Python中配置TensorFlow-GPU的完整方法 在深度学习项目开发中,模型训练动辄需要数小时甚至数天,而能否充分利用GPU资源,往往决定了整个研发流程的效率。如果你还在用CPU跑ResNet或Transformer,那可能连一个epoch都坚持不下来就放…

作者头像 李华
网站建设 2026/4/30 5:34:00

基于单片机的智能晾衣架控制系统设计【附代码】

📈 算法与建模 | 专注PLC、单片机毕业设计 ✨ 擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导,毕业论文、期刊论文经验交流。✅ 专业定制毕业设计✅ 具体问题可以私信或查看文章底部二维码在智能晾衣架控制系统的核心控制单元与驱动…

作者头像 李华
网站建设 2026/5/12 12:19:26

SP40P65NJ:一款高性能40V P沟道MOSFET深度解析

在电源管理与DC-DC转换器设计中,MOSFET的选择直接影响系统的效率、可靠性与成本。今天我们将推出的一款40V P沟道MOSFET——SP40P65NJ,结合其官方规格书,从关键参数、性能特点到封装信息进行全面梳理。一、核心规格摘要参数典型值条件漏源击穿…

作者头像 李华