news 2026/4/16 11:18:44

(39)AOP的实际案例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
(39)AOP的实际案例

事务处理

项目中的事务控制是在所难免的。在一个业务流程当中,可能需要多条DML语句共同完成,为了保证数据的安全,这多条DML语句要么同时成功,要么同时失败。这就需要添加事务控制的代码。例如以下伪代码:

class业务类1{publicvoid业务方法1(){try{// 开启事务startTransaction();// 执行核心业务逻辑step1();step2();step3();....// 提交事务commitTransaction();}catch(Exceptione){// 回滚事务rollbackTransaction();}}publicvoid业务方法2(){try{// 开启事务startTransaction();// 执行核心业务逻辑step1();step2();step3();....// 提交事务commitTransaction();}catch(Exceptione){// 回滚事务rollbackTransaction();}}publicvoid业务方法3(){try{// 开启事务startTransaction();// 执行核心业务逻辑step1();step2();step3();....// 提交事务commitTransaction();}catch(Exceptione){// 回滚事务rollbackTransaction();}}}class业务类2{publicvoid业务方法1(){try{// 开启事务startTransaction();// 执行核心业务逻辑step1();step2();step3();....// 提交事务commitTransaction();}catch(Exceptione){// 回滚事务rollbackTransaction();}}publicvoid业务方法2(){try{// 开启事务startTransaction();// 执行核心业务逻辑step1();step2();step3();....// 提交事务commitTransaction();}catch(Exceptione){// 回滚事务rollbackTransaction();}}publicvoid业务方法3(){try{// 开启事务startTransaction();// 执行核心业务逻辑step1();step2();step3();....// 提交事务commitTransaction();}catch(Exceptione){// 回滚事务rollbackTransaction();}}}//......

可以看到,这些业务类中的每一个业务方法都是需要控制事务的,而控制事务的代码又是固定的格式,都是:

try{// 开启事务startTransaction();// 执行核心业务逻辑//......// 提交事务commitTransaction();}catch(Exceptione){// 回滚事务rollbackTransaction();}

这个控制事务的代码就是和业务逻辑没有关系的“交叉业务”。以上伪代码当中可以看到这些交叉业务的代码没有得到复用,并且如果这些交叉业务代码需要修改,那必然需要修改多处,难维护,怎么解决?可以采用AOP思想解决。可以把以上控制事务的代码作为环绕通知,切入到目标类的方法当中。接下来我们做一下这件事,有两个业务类,如下:

packagecom.powernode.spring6.biz;importorg.springframework.stereotype.Component;@Component// 业务类publicclassAccountService{// 转账业务方法publicvoidtransfer(){System.out.println("正在进行银行账户转账");}// 取款业务方法publicvoidwithdraw(){System.out.println("正在进行取款操作");}}
packagecom.powernode.spring6.biz;importorg.springframework.stereotype.Component;@Component// 业务类publicclassOrderService{// 生成订单publicvoidgenerate(){System.out.println("正在生成订单");}// 取消订单publicvoidcancel(){System.out.println("正在取消订单");}}

注意,以上两个业务类已经纳入spring bean的管理,因为都添加了@Component注解。
接下来我们给以上两个业务类的4个方法添加事务控制代码,使用AOP来完成:

packagecom.powernode.spring6.biz;importorg.aspectj.lang.ProceedingJoinPoint;importorg.aspectj.lang.annotation.Around;importorg.aspectj.lang.annotation.Aspect;importorg.springframework.stereotype.Component;@Aspect@Component// 事务切面类publicclassTransactionAspect{@Around("execution(* com.powernode.spring6.biz..*(..))")publicvoidaroundAdvice(ProceedingJoinPointproceedingJoinPoint){try{System.out.println("开启事务");// 执行目标proceedingJoinPoint.proceed();System.out.println("提交事务");}catch(Throwablee){System.out.println("回滚事务");}}}

你看,这个事务控制代码是不是只需要写一次就行了,并且修改起来也没有成本。编写测试程序:

packagecom.powernode.spring6.test;importcom.powernode.spring6.biz.AccountService;importcom.powernode.spring6.biz.OrderService;importcom.powernode.spring6.service.Spring6Configuration;importorg.junit.Test;importorg.springframework.context.ApplicationContext;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;publicclassAOPTest2{@TestpublicvoidtestTransaction(){ApplicationContextapplicationContext=newAnnotationConfigApplicationContext(Spring6Configuration.class);OrderServiceorderService=applicationContext.getBean("orderService",OrderService.class);AccountServiceaccountService=applicationContext.getBean("accountService",AccountService.class);// 生成订单orderService.generate();// 取消订单orderService.cancel();// 转账accountService.transfer();// 取款accountService.withdraw();}}

执行结果:

通过测试可以看到,所有的业务方法都添加了事务控制的代码。

安全日志

需求是这样的:项目开发结束了,已经上线了。运行正常。客户提出了新的需求:凡事在系统中进行修改操作的,删除操作的,新增操作的,都要把这个人记录下来。因为这几个操作是属于危险行为。例如有业务类和业务方法:

packagecom.powernode.spring6.biz;importorg.springframework.stereotype.Component;@Component//用户业务publicclassUserService{publicvoidgetUser(){System.out.println("获取用户信息");}publicvoidsaveUser(){System.out.println("保存用户");}publicvoiddeleteUser(){System.out.println("删除用户");}publicvoidmodifyUser(){System.out.println("修改用户");}}
packagecom.powernode.spring6.biz;importorg.springframework.stereotype.Component;// 商品业务类@ComponentpublicclassProductService{publicvoidgetProduct(){System.out.println("获取商品信息");}publicvoidsaveProduct(){System.out.println("保存商品");}publicvoiddeleteProduct(){System.out.println("删除商品");}publicvoidmodifyProduct(){System.out.println("修改商品");}}

注意:已经添加了@Component注解。
接下来我们使用aop来解决上面的需求:编写一个负责安全的切面类

packagecom.powernode.spring6.biz;importorg.aspectj.lang.JoinPoint;importorg.aspectj.lang.annotation.Aspect;importorg.aspectj.lang.annotation.Before;importorg.aspectj.lang.annotation.Pointcut;importorg.springframework.stereotype.Component;@Component@AspectpublicclassSecurityAspect{@Pointcut("execution(* com.powernode.spring6.biz..save*(..))")publicvoidsavePointcut(){}@Pointcut("execution(* com.powernode.spring6.biz..delete*(..))")publicvoiddeletePointcut(){}@Pointcut("execution(* com.powernode.spring6.biz..modify*(..))")publicvoidmodifyPointcut(){}@Before("savePointcut() || deletePointcut() || modifyPointcut()")publicvoidbeforeAdivce(JoinPointjoinpoint){System.out.println("XXX操作员正在操作"+joinpoint.getSignature().getName()+"方法");}}

代码解释:

  • @Pointcut注解是定义一个切点表达式,用于指定哪些方法需要被拦截。
  • execution(…)匹配方法执行的连接点。
    • @Before:定义一个前置通知,在目标方法执行之前运行。
      切点表达式"savePointcut() || deletePointcut() || modifyPointcut()",表示当满足任一切点(save、delete 或 modify)时触发此通知。
@TestpublicvoidtestSecurity(){ApplicationContextapplicationContext=newAnnotationConfigApplicationContext(Spring6Configuration.class);UserServiceuserService=applicationContext.getBean("userService",UserService.class);ProductServiceproductService=applicationContext.getBean("productService",ProductService.class);userService.getUser();userService.saveUser();userService.deleteUser();userService.modifyUser();productService.getProduct();productService.saveProduct();productService.deleteProduct();productService.modifyProduct();}

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

YOLO训练成本太高?我们送你免费GPU token体验包

YOLO训练成本太高?我们送你免费GPU token体验包 在智能摄像头、工业质检线甚至无人机巡检的幕后,总能看到一个名字频繁出现:YOLO。它不是某个神秘缩写,而是“You Only Look Once”——一种将目标检测效率推向极致的设计哲学。今天…

作者头像 李华
网站建设 2026/4/10 20:36:37

YOLO模型支持InfluxDB时序数据库监控指标存储

YOLO 模型与 InfluxDB 时序数据库的监控集成实践 在智能制造车间的一条视觉检测产线上,工程师突然发现某台工控机的漏检率在下午三点开始持续上升。传统的排查方式需要手动登录设备、查看日志、运行诊断命令——整个过程耗时超过一小时。但如果这台设备已经将 YOLO …

作者头像 李华
网站建设 2026/4/14 14:39:00

2025最新!10个AI论文软件测评:研究生开题报告必备神器

2025最新!10个AI论文软件测评:研究生开题报告必备神器 2025年AI论文工具测评:精准匹配学术需求的高效助手 随着人工智能技术在学术领域的深入应用,越来越多的研究生开始依赖AI论文软件提升写作效率、优化研究流程。然而&#xff0…

作者头像 李华
网站建设 2026/4/15 7:34:32

YOLO模型训练支持Gradient Accumulation应对显存不足

YOLO模型训练支持Gradient Accumulation应对显存不足 在工业视觉系统日益复杂的今天,目标检测模型的部署需求正以前所未有的速度增长。从智能工厂的PCB缺陷识别,到城市交通中的多目标追踪,YOLO系列凭借其“一次前向、全图预测”的高效架构&a…

作者头像 李华