05-AOP的实际应用场景

news2026/4/2 2:50:58

AOP的实际案例

事务控制

在一个业务流程当中,可能需要多条DML语句共同完成,所以为了保证数据的安全需要添加事务控制的代码保证多条DML语句同时成功或失败

  • 业务类中的每一个业务方法控制事务的代码格式基本是固定的,我们可以采用AOP思想将这些交叉业务代码抽取出来,这样代码既能复用又易维护
class 业务类1{
    public void 业务方法1(){
        try{
            // 开启事务
            startTransaction();
            
            // 执行核心业务逻辑
            step1();
            step2();
            step3();
            ....
            
            // 提交事务
            commitTransaction();
        }catch(Exception e){
            // 回滚事务
            rollbackTransaction();
        }
    }
    
    public void 业务方法2(){
        try{
            // 开启事务
            startTransaction();
            
            // 执行核心业务逻辑
            step1();
            step2();
            step3();
            ....
            
            // 提交事务
            commitTransaction();
        }catch(Exception e){
            // 回滚事务
            rollbackTransaction();
        }
    }
}

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

第一步: 定义两个业务类(目标类)AccountService和OrderService以及业务方法(目标方法)

// 订单相关的业务类
@Service
public class OrderService {
    // 生成订单方法
    public void generate(){
        System.out.println("正在生成订单");
    }
    // 取消订单方法
    public void cancel(){
        System.out.println("正在取消订单");
    }
}

// 银行转账相关的业务类
@Service
public class AccountService {
    // 转账业务方法
    public void transfer(){
        System.out.println("正在进行银行账户转账");
    }
    // 取款业务方法
    public void withdraw(){
        System.out.println("正在进行取款操作");
    }
}

第二步: 定义一个事务相关的切面类TransactionAspect,把控制事务的代码写到环绕通知的方法中,根据切点表达式将通知切入到指定业务类的业务方法当中

@Component
@Aspect
public class TransactionAspect { // 事务切面类    
    @Around("execution(* com.powernode.spring6.service..*(..))")// 环绕通知
    public void aroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
        // 控制事务的代码
        try {
            // 前环绕
            System.out.println("开启事务");
            // 执行目标对象的目标方法
            proceedingJoinPoint.proceed();
            // 后环绕	
            System.out.println("提交事务");
        } catch (Throwable e) {
            System.out.println("回滚事务");
        }
    }
}

第三步: 在spring的配置文件开启组件扫描和自动代理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--开启组件扫描-->
    <context:component-scan base-package="com.powernode.spring6.service"/>
    <!--开启自动代理,spring容器在扫描类的时候会查看该类上是否有@Aspect注解,如果有则给这个切面类生成代理对象-->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>

第四步: 执行业务类的业务方法,查看环绕通知中的事务控制代码的执行情况

public class AOPTest2 {
    @Test
    public void testTransaction(){
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Spring6Configuration.class);
        OrderService orderService = applicationContext.getBean("orderService", OrderService.class);
        AccountService accountService = applicationContext.getBean("accountService", AccountService.class);
        // 执行orderService生成订单的方法
        orderService.generate();
        // 执行orderService取消订单的方法
        orderService.cancel();
        // 执行accountService转账的方法
        accountService.transfer();
        // 执行accountService取款的方法
        accountService.withdraw();
    }
}
开启事务
正在生成订单
提交事务

开启事务
正在取消订单
提交事务

开启事务
正在进行银行账户转账
提交事务

开启事务
正在进行取款操作
提交事务

安全日志

需求: 因为增删改操作是属于危险行为, 所以项目上线后凡是在系统中进行增删改操作的用户我们都需要记录下来

第一步: 定义业务类(目标类)UserServiceProductService及其业务方法(目标方法)

// 用户业务类
@Service
public class UserService {
    public void getUser(){
        System.out.println("获取用户信息");
    }
    public void saveUser(){
        System.out.println("保存用户");
    }
    public void deleteUser(){
        System.out.println("删除用户");
    }
    public void modifyUser(){
        System.out.println("修改用户");
    }
}
// 商户业务类
@Service
public class ProductService {
    public void getProduct(){
        System.out.println("获取商品信息");
    }
    public void saveProduct(){
        System.out.println("保存商品");
    }
    public void deleteProduct(){
        System.out.println("删除商品");
    }
    public void modifyProduct(){
        System.out.println("修改商品");
    }
}

第二步: 定义一个负责安全的切面类SecurityAspect,把记录安全日志的代码写到通知的方法中,根据切点表达式将通知切入到指定业务类的业务方法当中

@Component
@Aspect
public class SecurityAspect {
    // 抽取可重用的切点表达式
    @Pointcut("execution(* com.powernode.spring6.biz..save*(..))")
    public void savePointcut(){}

    @Pointcut("execution(* com.powernode.spring6.biz..delete*(..))")
    public void deletePointcut(){}

    @Pointcut("execution(* com.powernode.spring6.biz..modify*(..))")
    public void modifyPointcut(){}
	// 使用抽取好的切点表达式,指定通知只作用于增删改的方法
    @Before("savePointcut() || deletePointcut() || modifyPointcut()")
    public void beforeAdivce(JoinPoint joinpoint){
        System.out.println("XXX操作员正在操作"+joinpoint.getSignature().getName()+"方法");
    }
}

第三步: 在spring的配置文件开启组件扫描和自动代理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--开启组件扫描,biz也是业务层-->
    <context:component-scan base-package="com.powernode.spring6.biz"/>
    <!--开启自动代理,spring容器在扫描类的时候会查看该类上是否有@Aspect注解,如果有则给这个切面类生成代理对象-->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>

第四步: 执行业务类的业务方法,查看前置通知中记录安全日志的代码的执行情况

@Test
public void testSecurity(){
    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Spring6Configuration.class);
    UserService userService = applicationContext.getBean("userService", UserService.class);
    ProductService productService = applicationContext.getBean("productService", ProductService.class);
    // 调用userService对象的增删改查方法
    userService.getUser();
    userService.saveUser();
    userService.deleteUser();
    userService.modifyUser();
    
    // 调用productService对象的增删改查方法
    productService.getProduct();
    productService.saveProduct();
    productService.deleteProduct();
    productService.modifyProduct();
}
获取用户信息
XXX操作员正在操作saveUser方法
保存用户
XXX操作员正在操作deleteUser方法
删除用户
XXX操作员正在操作modifyUser方法
修改用户

获取商品信息
XXX操作员正在操作saveProduct方法
保存商品
XXX操作员正在操作deLeteProduct方法
删除商品
XXX操作员正在操作modifyProduct方法
修改商品

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

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

相关文章

docker安装(超详细)

一.引言 本安装教程参考Docker官方文档&#xff0c;地址如下&#xff1a;https://docs.docker.com/engine/install/centos/ 二.卸载旧版docker(第一次安装可忽略) 首先如果系统中已经存在旧的Docker&#xff0c;则先卸载&#xff1a; yum remove docker \docker-client \docker…

Excel【毫秒】/【秒】转换成【时分秒】/【分秒】

1、毫秒转换秒 2、秒转换时分秒 3、秒转换分秒

导轨式安装压力应变桥信号处理差分信号输入转换变送器0-10mV/0-20mV/0-±10mV/0-±20mV转0-5V/0-10V/4-20mA

主要特性 DIN11 IPO 压力应变桥信号处理系列隔离放大器是一种将差分输入信号隔离放大、转换成按比例输出的直流信号导轨安装变送模块。产品广泛应用在电力、远程监控、仪器仪表、医疗设备、工业自控等行业。此系列模块内部嵌入了一个高效微功率的电源&#xff0c;向输入端和输…

mac卸载软件工具CleanMyMac X4.15永久版下载

如今电脑成为大多数人工作的工具&#xff0c;使用得越久就越需要清理垃圾软件。系统垃圾、废纸娄垃圾、大型和旧文件这些通常都占用了我们的电脑几G的空间。 想要清除不必要的垃圾文件&#xff0c;可以使用mac卸载软件CleanMyMac X&#xff0c;这款清理垃圾软件可以智能扫描Ma…

基于DevEco Studio的OpenHarmony应用原子化服务(元服务)入门教程

一、创建项目 二、创建卡片 三、应用服务代码 Index.ets Entry Component struct Index {State TITLE: string OpenHarmony;State CONTEXT: string 创新召见未来&#xff01;;build() {Row() {Column() {Text(this.TITLE).fontSize(30).fontColor(0xFEFEFE).fontWeight(…

灵活多变的保护——OV通配符证书

随着互联网发展&#xff0c;网站安全性日益关乎企业和个人的信誉与用户体验。而在诸多SSL证书中&#xff0c;OV通配符证书以其灵活多变的特点成为了一个备受推崇的选择。本文将介绍什么是OV通配符证书以及其在网站保护方面的优势。 OV通配符证书是一种提供全面SSL加密保护的数…

2023-11-06 LeetCode每日一题(最大单词长度乘积)

2023-11-06每日一题 一、题目编号 318. 最大单词长度乘积二、题目链接 点击跳转到题目位置 三、题目描述 给你一个字符串数组 words &#xff0c;找出并返回 length(words[i]) * length(words[j]) 的最大值&#xff0c;并且这两个单词不含有公共字母。如果不存在这样的两个…

每天一个公众号干货|定时群发教程

每天一个公众号排版小知识&#xff0c;今天分享的是定时群发功能&#xff0c;一次性给你讲清楚 公众号定时群发可以让我们在固定的时间精准的发表文章&#xff0c;这对发文强迫症的小伙伴来时是一个非常神仙的功能&#xff0c;如果群发之前有事耽误发表了&#xff0c;也可以使…

【Orangepi Zero2 全志H616】驱动舵机控制 / Linux定时器(signal、setitimer)

一、SG90舵机开发 舵机基本介绍 二、Linux定时器 signal 函数setitimer 函数原型signal、setitimer函数API调用 三、舵机 软件PWM实现 一、SG90舵机开发 舵机基本介绍 如下图所示&#xff0c;最便宜的舵机sg90&#xff0c;常用三根或者四根接线&#xff0c;黄色为PWM信号控…

简单工厂VS工厂方法

工厂方法模式–制造细节无需知 前面介绍过简单工厂模式&#xff0c;简单工厂模式只是最基本的创建实例相关的设计模式。在真实情况下&#xff0c;有更多复杂的情况需要处理。简单工厂生成实例的类&#xff0c;知道了太多的细节&#xff0c;这就导致这个类很容易出现难维护、灵…

Eolink Apikit 版本更新:「数据字典」功能上线、支持 MongoDB 数据库操作、金融行业私有化协议、GitLab 生成 API 文档...

&#x1f389; 新增 搭建自定义接口协议架构&#xff0c;支持快速适配金融行业各类型私有协议的导入、编辑和展示。 数据字典功能上线&#xff0c;支持以数据字典的形式管理参数枚举值&#xff1b; 数据库连接支持 MongoDB 数据库操作&#xff1b; 基于 Apikit 类型导入 API…

DDD学习笔记

1)ddd&#xff1a; 软件复杂性的应对之道。 但是不是说&#xff1a;redis这种不会使用。 开发过程中&#xff0c;一直面临的一种复杂性。 是一种架构思想: 领域之间的组合。 让开发软件具有搭积木的感觉。 领域的核心是边界。 以领域划分为基础。 以通用语言为建设…

1-3 docker 安装 prometheus

一、环境 1、环境准备 安装Docker 镜像加速 安装 docker 检查版本 安装Docker-compose 二、Docker-compose 安装 Prometheus 1、【方式一】手动创建 docker-compose 和 配置文件 创建prometheus监控的文件夹 创建alertmanager的配置文件 - config.yml 新建grafana的…

YOLOv8 C2f模块融合shuffleAttention注意力机制

1. 引言 1.1YOLOv8直接添加注意力机制 yolov8添加注意力机制是一个非常常见的操作&#xff0c;常见的操作直接将注意力机制添加至YOLOv8的某一层之后&#xff0c;这种改进特别常见。 示例如下&#xff1a; 新版yolov8添加注意力机制&#xff08;以NAMAttention注意力机制为例…

jsonlite库

jsonlite是一个R语言中用于处理JSON数据的库。它提供了一组简单而强大的函数&#xff0c;用于解析、生成和转换JSON数据。 使用jsonlite库&#xff0c;您可以轻松地将JSON数据解析为R语言中的数据结构&#xff0c;如列表或数据框。您还可以将R语言中的数据结构转换为JSON格式&…

解决vue3父组件执行子组件方法报错:TypeError: Cannot read properties of null

现象&#xff1a; 父组件执行子组件的代码&#xff1a; 原因&#xff1a; Vue3使用的所有变量除了来自父组件传值的props以外&#xff0c;其他的html绑定的所有本地变量都必须通过return导出&#xff01; 这一点是vue3 最坑爹的一点。很容易忘记。 解决办法&#xff1a;使用t…

世界500强通信巨头全面推进SDLC,打造高质量的数字解决方案

某通信巨头是世界500强企业&#xff0c;全球领先的信息与通信技术解决方案供应商。多年来&#xff0c;该公司在数字化领域一直走在前列&#xff0c;打造了大量数字化创新解决方案和成功案例&#xff0c;助力合作伙伴更好地理解和应用数字化技术&#xff0c;实现自身的发展和价值…

c语言 简单认识 指针和结构体

指针 代码 #include <stdio.h>int main(){int a 10;//指针类型需要与变量的类型相同&#xff0c;且后面需要添加一个*符号&#xff08;注意这里不是乘法运算&#xff09;表示是对于类型的指针int * p &a; //这里的&并不是进行按位与运算&#xff0c;而是取…

Kubernetes 的四个网络挑战

Kubernetes 的主要职责之一是在应用程序之间共享节点。由于这些应用程序需要相互通信并与外部世界通信&#xff0c;因此网络是一个基本的需求。 Kubernetes 托管的分布式应用程序架构 来自 Kubernetes 集群外部的请求通常通过负责将它们代理到适当服务的路由器或 API 网关进行…

mac安装python3

文章目录 1. 安装1.1 brew安装&#xff08;失败&#xff09;2. 下载安装包 2. 查看版本3. 配置 1. 安装 1.1 brew安装&#xff08;失败&#xff09; brew install python3下载完成后报错&#xff1a;Error: python3.10: unknown or unsupported macOS version: :dunno 解决&a…