Java SpringAOP简介

简介

官方介绍:
SpringAOP的全称是(Aspect Oriented Programming)中文翻译过来是面向切面编程,AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

个人理解:
java开发过程中,若多个模块方法执行前后需要统一功能,例如日志记录,权限校验,事务,效率(程序执行时间)等。若一一修改代码会比较麻烦且代码冗余,我们可以通过切面+注解的方式,给各模块方法增加简便的统一的功能。

SpringAOP的应用场景

日志记录
权限验证(SpringSecurity有使用)
事务控制(调用方法前开启事务, 调用方法后提交关闭事务 )
效率检查(检测方法运行时间)
数据源代理(seata里面,获取到数据源连接执行的sql)
缓存优化 (第一次调用查询数据库,将查询结果放入内存对象, 第二次调用, 直接从内存对象返回,不需要查询数据库 )

核心概念

切面(Aspect):切面是一个概念,是一个模块化的单元,它包含了与特定关注点相关的通知和切点的定义。通知指的是在执行某个切点时要执行的代码逻辑,例如前置通知、后置通知、环绕通知等。切点指的是定义了真正需要被增强的连接点,例如方法调用或者方法执行等。

连接点(Join Point):连接点指代是需要被增强的地方,程序执行过程中的一个特定点,例如方法调用、方法执行、构造函数调用等。切点实际上就是连接点的选择,用来指定需要被切入的具体方法。

通知(Advice):通知是切面中的连接点执行前,执行后需要增加的具体代码逻辑,它定义了在特定切点执行前、执行后或执行中进行的操作。常见的通知类型有前置通知(Before Advice)、后置通知(After Advice)、环绕通知(Around Advice)等。

切点表达式(Pointcut Expression):切点表达式用于指定需要被增强的具体连接点,可以通过AspectJ注解或者Spring AOP XML配置来定义。

实现方式

<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version>
</dependency>

Springboot 项目无需引入上面jar包。

定义切点

指定需要增强的方法,切点表达式写法参考:
https://blog.51cto.com/u_16099229/9422977

// 定义切点,匹配某个特定的方法或包下的所有方法@Pointcut(value = "execution(* * ..StudentServiceImpl.createStudent(..))")public void serviceMethods() {}

通知类型

@Before:前置通知,若通知程序异常不执行连接点;
@After:后置通知,连接点是否异常,都会执行;
@AfterReturning:后置通知,连接点正常才会执行;
@AfterThrowing:后置通知,连接点异常才会执行;
@Around:环绕通知,可以作用于连接点前或连接点后(joinPoint.proceed()前的是连接点前,后连接点后),可以修改连接点返回值。

执行循序:

@Around > @Before > 连接点中的程序 > @AfterReturning/@AfterThrowing > @After > @Around

通知调用示例

@Slf4j
@Aspect
@Component
public class LoggingAspect {// 定义切点,匹配某个特定的方法或包下的所有方法@Pointcut(value = "execution(* * ..StudentServiceImpl.createStudent(..))")public void serviceMethods() {}/*** Before:前置通知,带方法参数的切面* 切面方法有参数时要求参数是JoinPoint类型,参数名自定义,该参数就代表了连接点方法,即createStudent方法* 使用该参数可以获取切入点表达式、切入点方法签名、目标对象等* <p>* (1)访问修饰符权限是public* (2)方法的返回值是void* (3)方法名称是自定义* (4)可以没有方法形式参数,如果有,必为JoinPoint类型* (5)必须使用@Before注解来声明切入的时机是前切功能和切入点*/@Before(value = "serviceMethods()")public void beforeAddStudent(JoinPoint joinPoint) {log.info("前置通知(Before):若异常不执行目标程序");log.info("前置通知(Before):方法签名:{}", joinPoint.getSignature());log.info("前置通知(Before):方法名称:{}", joinPoint.getSignature().getName());Object[] args = joinPoint.getArgs();log.info("前置通知(Before):方法参数:{}", Arrays.toString(args));}@After(value = "serviceMethods()")public void afterAddStudent() {log.info("后置通知(After):目标程序异常继续执行");}@AfterReturning(value = "serviceMethods()")public void afterReturningAddStudent() {log.info("后置通知(AfterReturning):目标程序正常才会继续执行");}@AfterThrowing(value = "serviceMethods()")public void afterThrowingAddStudent() {log.info("后置通知(AfterThrowing):目标异常正常才会继续执行");}/*** 环绕通知,环绕通知可以改变方法返回值* <p>* 能完全控制目标代码是否执行,并可以在执行前后、抛异常后执行任意拦截代码*//*环绕通知:@Around(切入点表达式)1、环绕通知是最重要的一个通知,他表示在连接点方法的前或者后都可以执行,它的本质就是jdk动态代理的invoke方法的method参数2、定义格式a、publicb、必须有返回值,类型为Object2、连接点出现异常时,可以增加try catch处理,否则异常向上一级抛出。*/@Around(value = "serviceMethods()")public Object aroundAddStudent(ProceedingJoinPoint joinPoint) throws Throwable {log.info("环绕通知(Around):连接点前");try {Object retVal = joinPoint.proceed();log.info("retVal : {}", retVal);log.info("环绕通知(Around):连接点后");return retVal;} catch (Exception e) {log.info("环绕通知(Around):连接点出现异常后");return new StudentResult();}}
}

AOP中使用自定义注解

自定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MetricTime {String value();
}

注解+环绕切面

@Slf4j
@Aspect
@Component
public class LoggingAspect {// 定义切点,匹配某个特定的方法或包下的所有方法@Pointcut(value = "execution(* * ..StudentServiceImpl.createStudent(..))")public void serviceMethods() {}@Around("@annotation(metricTime)")public Object around(ProceedingJoinPoint joinPoint, MetricTime metricTime) throws Throwable {String name = metricTime.value();long start = System.currentTimeMillis();System.out.println("[Metrics] " + name);log.info("环绕通知(Around):连接点前:{}", metricTime.value());try {return joinPoint.proceed();} catch (Exception e) {log.error("环绕通知(Around):连接点后异常:{}", e.getMessage());return null;} finally {long t = System.currentTimeMillis() - start;log.info("[Metrics] {}: {}ms", name, t);}}
}

在连接点上增加自定义注解
在这里插入图片描述
测试调用结果
在这里插入图片描述

文档参考网址:

https://blog.csdn.net/xuewenyu_/article/details/134246558
https://blog.51cto.com/u_16099229/9422977

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

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

相关文章

SpringBatch文件读写ItemWriter,ItemReader使用详解

SpringBatch文件读写ItemWriter&#xff0c;ItemReader使用详解 1. ItemReaders 和 ItemWriters1.1. ItemReader1.2. ItemWriter1.3. ItemProcessor 2.FlatFileItemReader 和 FlatFileItemWriter2.1.平面文件2.1.1. FieldSet 2.2. FlatFileItemReader2.3. FlatFileItemWriter 3…

AI 绘画|Midjourney设计Logo提示词

你是否已经看过许多别人分享的 MJ 咒语&#xff0c;却仍无法按照自己的想法画图&#xff1f;通过学习 MJ 的提示词逻辑后&#xff0c;你将能够更好地理解并创作自己的“咒语”。本文将详细拆解使用 MJ 设计 Logo 的逻辑&#xff0c;让你在阅读后即可轻松上手&#xff0c;制作出…

打包一个自己的Vivado IP核

写在前面 模块复用是逻辑设计人员必须掌握的一个基本功&#xff0c;通过将成熟模块打包成IP核&#xff0c;可实现重复利用&#xff0c;避免重复造轮子&#xff0c;大幅提高我们的开发效率。 接下来将之前设计的串口接收模块和串口发送模块打包成IP核&#xff0c;再分别调用…

【深度学习】FaceChain-SuDe,免训练,AI换脸

https://arxiv.org/abs/2403.06775 FaceChain-SuDe: Building Derived Class to Inherit Category Attributes for One-shot Subject-Driven Generation 摘要 最近&#xff0c;基于主体驱动的生成技术由于其个性化文本到图像生成的能力&#xff0c;受到了广泛关注。典型的研…

深度学习入门——神经网络

前言 神经网络可以帮助自动化设定权重 具体地讲&#xff0c;神经网络的一个重要性质是它可以自动地从数据中学习到合适的权重参数 从感知机到神经网络 神经网络的例子 中间层aka隐藏层 复习感知机 偏置b 并没有被画出来。如果要明确地表示出b&#xff0c;可以像图3-3那样做…

Large Language Model系列之一:语言模型与表征学习(Language Models and Representation Learning)

语言模型与表征学习&#xff08;Language Models and Representation Learning&#xff09; 1 语言模型 N-Gram模型 from collections import defaultdictsentences [The swift fox jumps over the lazy dog.,The swift river flows under the ancient bridge.,The swift br…

华为1000人校园实验记录

在这里插入代码片1000人校园区网设计 1、配置Eth-trunk实现链路冗余 vlan 900 管理WLAN #接入SW8 操作&#xff1a;sys undo in en sysname JR-SW8 int Eth-Trunk 1 mode lacp-static trunkport g0/0/1 0/0/2 port link-type trunk port trunk allow-pass vlan 200 900 qu vla…

模拟器小程序/APP抓包(Reqable+MUMU模拟器)

一、使用adb连接上MUMU模拟器 打开多开器点击ADB图标 连接模拟器端口&#xff1a; adb connect 127.0.0.1:16384列出已连接的设备&#xff1a; adb devices正常会显示MuMu的设备已连接 二、下载Reqable 1.下载链接&#xff1a;客户端下载 | Reqable 2.文档链接&#xff1a;…

redis基本类型和订阅

redis-cli -h <host> -p <port> -a <password> 其中&#xff0c;< host>是Redis服务器的主机名或IP地址&#xff0c;< port>是Redis服务器的端口号&#xff0c;< password>是Redis服务器的密码&#xff08;如果有的话&#xff09;。 set …

LLM基础模型系列:Prompt-Tuning

------->更多内容&#xff0c;请移步“鲁班秘笈”&#xff01;&#xff01;<------ 大型预训练语言模型的规模不断扩大&#xff0c;在许多自然语言处理 &#xff08;NLP&#xff09; 基准测试中取得了最先进的结果。自GPT和BERT开发以来&#xff0c;标准做法一直是在下游…

数字化教育资源如何适应人工智能时代

01 教育资源应动态适应一线教学需求 用好数字化教育资源是一项系统工程&#xff0c;涉及教育教学的各个方面&#xff0c;包括教师和学生的教育观念与技术观念、信息技术素养&#xff0c;以及课程教学改革、教师培训等。还涉及数字化教育资源提供方的服务&#xff0c;如技术支持…

【STM32嵌入式系统设计与开发---拓展】——1_9_1上拉输入和下拉输入

在使用GPIO引脚时&#xff0c;上拉输入和下拉输入的选择取决于外部电路的特性和应用需求。以下是它们各自的应用场景&#xff1a; 1、上拉输入&#xff08;Pull-up Input&#xff09; 用途: 当默认状态需要为高电平时。 避免引脚悬空&#xff08;floating&#xff09;导致的…

计算机网络——网络层(路由选择协议、路由器工作原理、IP多播、虚拟专用网和网络地址转换)

目录 路由选择协议 因特网的路由选择协议特点 路由信息协议RIP RIP衡量目的网络距离 RIP选择路由器的方式 RIP具有以下三个重要特点 RIP的基本工作流程 RIP的距离向量算法 ​编辑 ​编辑 RIP存在的问题——“坏消息传播得慢” RIP的封装 开放最短路径优先协议OSPF…

昇思25天学习打卡营第23天|基于MindSpore的Pix2Pix实现图像转换

Pix2Pix实现图像转换 Pix2Pix概述 Pix2Pix是基于条件生成对抗网络&#xff08;cGAN, Condition Generative Adversarial Networks &#xff09;实现的一种深度学习图像转换模型&#xff0c;该模型是由Phillip Isola等作者在2017年CVPR上提出的&#xff0c;可以实现语义/标签到…

【贪心算法】贪心算法30题

一、贪心算法简介 证明贪心策略正确性的常用方法&#xff1a;直接证明、交换论证法、反证法、分类讨论… 二、相关编程题 2.1 柠檬水找零 题目链接 860. 柠檬水找零 - 力扣&#xff08;LeetCode&#xff09; 题目描述 算法原理 提示&#xff1a;最优解和贪心解唯一可能不同…

《昇思25天学习打卡营第19天|Diffusion扩散模型》

什么是Diffusion Model&#xff1f; 什么是Diffusion Model? 如果将Diffusion与其他生成模型&#xff08;如Normalizing Flows、GAN或VAE&#xff09;进行比较&#xff0c;它并没有那么复杂&#xff0c;它们都将噪声从一些简单分布转换为数据样本&#xff0c;Diffusion也是从…

共建特色基地 协同互促育人

作为芯片和集成电路、人工智能、智能网联车等临港重点产业布局的知识密集型相关企业&#xff0c;核心技术人才和技术骨干是公司参与全球竞争的重要核心竞争力之一。 知从科技通过不断的创新和规范&#xff0c;在深化产教融合、校企合作、“双师型”、联合办学协同育人、产业人…

git回退分支版本git reset --hard HEAD

git回退分支版本git reset --hard HEAD git reset --hard HEAD 上面命令清除本地所有修改&#xff0c;与下面相似&#xff1a; git reset --hard origin/master 等同于&#xff1a; git reset --hard HEAD~0 说明&#xff1a; HEAD 当前版本 HEAD^ 上一个版本 HEAD^^ 上上…

Linux - 冯-诺依曼体系结构、初始操作系统

目录 冯•诺依曼体系 结构推导 内存提高效率的方法 数据的流动过程 体系结构相关知识 初始操作系统 定位 设计目的 操作系统之上之下分别有什么 管理精髓&#xff1a;先描述&#xff0c;再组织 冯•诺依曼体系 结构推导 计算机基本工作流程图大致如下&#xff1a; 输入设备&a…

支付宝低代码搭建电商小程序,无需编程,可视化操作

大家好&#xff0c;我是小悟 在数字化浪潮的推动下&#xff0c;为了更快速、高效地搭建电商小程序&#xff0c;支付宝低代码平台凭借其独特优势&#xff0c;为商家提供了便捷的解决方案。 支付宝低代码平台犹如一座精心打造的智慧工坊&#xff0c;让电商小程序的搭建变得轻而易…