第17章-Spring AOP经典应用场景

news2024/11/26 4:38:46

文章目录

    • 一、日志处理
    • 二、事务控制
    • 三、参数校验
    • 四、自定义注解
    • 五、AOP 方法失效问题
      • 1. ApplicationContext
      • 2. AopContext
      • 3. 注入自身
    • 六、附录
      • 1. 示例代码

AOP 提供了一种面向切面操作的扩展机制,通常这些操作是与业务无关的,在实际应用中,可以实现:日志处理、事务控制、参数校验和自定义注解等功能。

Spring AOP 的原理参阅:《Spring中的AOP和动态代理》

一、日志处理

在调试程序时,如果需要在执行方法前打印方法参数,或者在执行方法后打印方法返回结果,可以使用切面来实现。

@Slf4j
@Aspect
@Component
public class LoggerAspect {

    @Around("execution(* cn.codeartist.spring.aop.sample.*.*(..))")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        // 方法执行前日志
        log.info("Method args: {}", joinPoint.getArgs());
        Object proceed = joinPoint.proceed();
        // 方法执行后日志
        log.info("Method result: {}", proceed);
        return proceed;
    }
}

二、事务控制

Spring 提供的声明式事务也是基于 AOP 来实现的,在需要添加事务的方法上面使用 @Transactional 注解。

@Service
public class DemoService {

    @Transactional(rollbackFor = Exception.class)
    public void insertBatch() {
        // 带事务控制的业务操作
    }
}

三、参数校验

如果需要在方法执行前对方法参数进行校验时,可以使用前置通知来获取切入点方法的参数,然后进行校验。

@Slf4j
@Aspect
@Component
public class ValidatorAspect {

    @Before("execution(* cn.codeartist.spring.aop.sample.*.*(..))")
    public void doBefore(JoinPoint joinPoint) {
        // 方法执行前校验参数
        Object[] args = joinPoint.getArgs();
    }
}

四、自定义注解

因为 AOP 可以拦截到切入点方法,Spring 也支持通过注解的方式来定义切点表达式,所以可以通过 AOP 来实现自定义注解的功能。

例如,自定义一个注解来实现声明式缓存,把方法的返回值进行缓存。

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Cacheable {

    /**
     * 缓的Key
     */
    String key();

    /**
     * 缓存过期时间
     */
    long timeout() default 0L;

    /**
     * 缓存过期时间单位(默认:毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
}

然后定义一个切片来实现常规的缓存操作,先读缓存,缓存不存在时执行方法,然后把方法的返回结果进行缓存。

@Aspect
@Component
public class AnnotationAspect {

    @Around("@annotation(cacheable)")
    public Object doAround(ProceedingJoinPoint joinPoint, Cacheable cacheable) throws Throwable {
        // 自定义缓存逻辑
        return joinPoint.proceed();
    }
}

五、AOP 方法失效问题

Spring AOP 的原理是在原有方法外面增加一层代理,所以在当前类调用 AOP 方法时,因为 this 指向的是当前对象,而不是代理对象,所以 AOP 会失效。

@Service
public class DemoService {

    public void insert() {
        // 该方法事务会失效
        insertBatch();
    }

    @Transactional(rollbackFor = Exception.class)
    public void insertBatch() {
        // 带事务控制的业务操作
    }
}

解决这个问题的常用方法有下面三种:

1. ApplicationContext

使用 ApplicationContext 来手动获取 Bean 对象,来调用 AOP 方法:

@Service
public class DemoService {

    @Autowired
    private ApplicationContext applicationContext;

    public void insert() {
        DemoService demoService = applicationContext.getBean(DemoService.class);
        demoService.insertBatch();
    }

    @Transactional(rollbackFor = Exception.class)
    public void insertBatch() {
        // 带事务控制的业务操作
    }
}

2. AopContext

使用 AopContext 工具类来获取当前对象的代理对象。

@Service
public class DemoService {

    public void insert() {
        ((DemoService) AopContext.currentProxy()).insertBatch();
    }

    @Transactional(rollbackFor = Exception.class)
    public void insertBatch() {
        // 带事务控制的业务操作
    }
}

3. 注入自身

使用 Spring 注入自身来调用 AOP 方法:

@Service
public class DemoService {

    @Autowired
    private DemoService that;

    public void insert() {
        that.insertBatch();
    }

    @Transactional(rollbackFor = Exception.class)
    public void insertBatch() {
        // 带事务控制的业务操作
    }
}

六、附录

1. 示例代码

Gitee 仓库:https://gitee.com/code_artist/spring

在这里插入图片描述

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

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

相关文章

5. C++类的封装

一、类的封装 封装的含义&#xff1a; 所有属性都是私有的&#xff0c;外部不能直接访问提供与属性相关的成员函数&#xff0c;间接访问属性 模板代码&#xff1a; #include <iostream> using namespace std;class Clock { private:int hour, minute, second; public…

《UNIX 传奇:历史与回忆》读后感

《UNIX 传奇&#xff1a;历史与回忆》 是 bwk&#xff08;Brian W. Kernighan&#xff09;2019 年的新作&#xff0c;回忆了 UNIX 在大半个世纪的风雨历程&#xff0c;是一本引人入胜的书籍。通过对 UNIX 操作系统的历史和发展进行详细的叙述和回顾&#xff0c;让我对这个操作系…

浅析基于安防监控EasyCVR视频汇聚融合技术的运输管理系统

一、项目背景 近年来&#xff0c;随着物流行业迅速发展&#xff0c;物流运输费用高、运输过程不透明、货损货差率高、供应链协同能力差等问题不断涌现&#xff0c;严重影响了物流作业效率&#xff0c;市场对于运输管理数字化需求愈发迫切。当前运输行业存在的难题如下&#xf…

Java volatile关键字分析

每个线程创建时&#xff0c;JVM会为其创建一份私有的工作内存&#xff08;栈空间&#xff09;&#xff0c;不同线程的工作内存之间不能直接互相访问 JMM规定所有的变量都存在主内存&#xff0c;主内存是共享内存区域&#xff0c;所有线程都可以访问 线程对变量进行读写&#xf…

计算机组成原理-笔记-第三章

目录 计算机组成原理——第三章——存储系统 1、基本概念 &#xff08;1&#xff09;分类 &#xff08;2&#xff09;总结 2、主存储器&#xff08;基本原理&#xff09; &#xff08;1&#xff09;译码器、控制电路、存储单元 &#xff08;容量计算&#xff09; &…

匈牙利算法详解

匈牙利算法(Hungarian Algorithm)是一种组合优化算法(combinatorial optimization algorithm)&#xff0c;用于求解指派问题(assignment problem)&#xff0c;算法时间复杂度为O(N^3)。Harold Kuhn发表于1955年&#xff0c;由于该算法基于两位匈牙利数学家的早期研究成果&#…

数字IC流片经历有多重要?怎样才能有流片机会?

都说拥有流片经验可以显示你在实际项目中的实践能力和对整个设计流程的了解程度&#xff0c;流片经历的重要性不言而喻。 什么是芯片流片 像流水线一样通过一系列工艺步骤制造芯片&#xff0c;这就是流片。在芯片制造过程中一般有两段时间可以叫作流片。 流片&#xff1a;英…

分布式测试插件 pytest-xdist 使用详解

目录 使用背景&#xff1a; 使用前提&#xff1a; 使用快速入门&#xff1a; 使用小结&#xff1a; 使用背景&#xff1a; 大型测试套件&#xff1a;当你的测试套件非常庞大&#xff0c;包含了大量的测试用例时&#xff0c;pytest-xdist可以通过并行执行来加速整体的测试过…

Unity数字可视化学校_昼夜(二)

1、时间设置&#xff1a; 2、新建夜晚 3、新建侧置球&#xff08;BOX&#xff09;,测试灯光强度 降低亮度 色调&#xff1a;冷色调 4、自发光 新建shader 灯光控制 道路线&#xff1a; 建筑&#xff1a; 夜晚加灯光&#xff1a; 玻璃&#xff1a; 加大灯光数量&#xff1a; 边缘…

深入理解负载均衡原理及算法

1. 前言 在互联网早期,网络还不是很发达,上网用户少,流量相对较小,系统架构以单体架构为主。但如今在互联网发达的今天,流量请求动辄百亿、甚至上千亿,单台服务器或者实例已完全不能满足需求,这就有了集群。不论是为了实现高可用还是高性能,都需要用到多台机器来扩展服…

校对软件助力司法公正:确保法律文书准确无误

校对软件在司法系统中的应用可以助力司法公正&#xff0c;确保法律文书的准确性和无误性。以下是校对软件如何发挥作用&#xff1a; 1.确保准确性&#xff1a;校对软件可以自动检查法律文书中的语法、拼写和标点等方面的错误。通过及时发现和修正这些错误&#xff0c;可以确保文…

自监督去噪:Recorrupted-to-Recorrupted原理分析与总结

文章目录 1. 方法原理1.1 相关研究1.2 研究思路1.3 小结 2. 实验结果3. 总结 文章地址: https://ieeexplore.ieee.org/document/9577798/footnotes#footnotes 参考博客: https://github.com/PangTongyao/Recorrupted-to-Recorrupted-Unsupervised-Deep-Learning-for-Image-Den…

C++如何改变文字的颜色(不同字显示不同颜色)

许多同学们在制作c游戏的时候只有黑白两种颜色。就像si人了一样 非常影响视觉效果&#xff0c;显得十分不好看&#xff0c;因此&#xff0c;我决定发一个改变文字颜色的文章&#xff01; 下面介绍方法&#xff1a; 在了解程序之前&#xff0c;首先好了解光的三原色已经三原色…

数据结构刷题训练——链表篇(三)

目录 文章目录 前言 1. 题目一&#xff1a;环形链表Ⅱ 1.1 思路 1.2 分析 1.3 题解 1.4 方法二 2. 题目二&#xff1a;复制带随机指针的链表 2.1 思路 2.2 分析 2.3 题解 总结 前言 在这个专栏博客中&#xff0c;我们将提供丰富的题目资源和解题思路&#xff0c;帮助读者逐步提…

浅谈智能配电房在海岛中的应用

安科瑞 华楠 摘要&#xff1a;以海陵岛旅游区海岛智能配电房设计方案为研究对象,从功能设计、逻辑设计和拓扑设计三方面进行 分析,得出契合海陵岛实际和海岛特点的智能配电房方案设计。通过对设计方案研究,总结提炼了海岛智 能配电房组成要素,为进一步提炼统一规范的智能配电房…

【深度学习】【风格迁移】Zero-shot Image-to-Image Translation

论文&#xff1a;https://arxiv.org/abs/2302.03027 代码&#xff1a;https://github.com/pix2pixzero/pix2pix-zero/tree/main 文章目录 Abstract1. Introduction相关工作3. Method Abstract 大规模文本到图像生成模型展示了它们合成多样且高质量图像的显著能力。然而&#x…

【网络编程】实现一个简单多线程版本TCP服务器(附源码)

TCP多线程 &#x1f335;预备知识&#x1f384; Accept函数&#x1f332;字节序转换函数&#x1f333;listen函数 &#x1f334;代码&#x1f331;Log.hpp&#x1f33f;Makefile☘️TCPClient.cc&#x1f340;TCPServer.cc&#x1f38d; util.hpp &#x1f335;预备知识 &…

未来C#上位机软件发展趋势

C#上位机软件迎来新的发展机遇。随着工业自动化的快速发展&#xff0c;C#作为一种流行的编程语言在上位机软件领域发挥着重要作用。未来&#xff0c;C#上位机软件可能会朝着以下几个方向发展&#xff1a; 1.智能化&#xff1a;随着人工智能技术的不断演进&#xff0c;C#上位机…

数据结构--最小生成树

数据结构–最小生成树 连通图 \color{red}连通图 连通图的生成树是 包含图中全部顶点的一个极小连通子图 \color{red}包含图中全部顶点的一个极小连通子图 包含图中全部顶点的一个极小连通子图。 若图中顶点数为n&#xff0c;则它的生成树含有 n-1 条边。对生成树而言&#xff…

RFID技术助力半导体制造行业自动化生产

由于芯片短缺问题和近2年海运拥堵和成本上升等因素&#xff0c;致使全球资本对于芯片制造工厂的投入增大&#xff0c;而中兴、华为的例子已经凸显出国产半导体供应链的重要性&#xff0c;除去地缘政治上的意义&#xff0c;发展半导体其实是中国经济的转型的必走之路。 半导体生…