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…

opencv—常用函数学习_“干货“_4

目录 十二、图像平滑滤波 均值滤波 (blur) 方框滤波 (boxFilter) 中值滤波 (medianBlur) 高斯滤波 (GaussianBlur) 双边滤波 (bilateralFilter) 自定义滤波器 (filter2D) 边缘保留滤波 (edgePreservingFilter) 快速非局部均值去噪 (fastNlMeansDenoising) 彩色图像的快…

Canvas API

Canvas API中文文档: canvas API中文网 - Canvas API中文文档首页地图 Web 开发技术: Canvas API - Web API | MDN (mozilla.org) HTML5 Canvas: The HTML5 Canvas Handbook (bucephalus.org)

前端内容之常用置标

最近由于换了项目组&#xff0c;目前负责需求全部是前端任务&#xff0c;为了方便后续查看&#xff0c;在此记录下&#xff01; 拓尔思常用置标 获取指定栏目的指定字段(数据库字段)的栏目信息 获取一级栏目的栏目名称 autolink为true,代表产生链接;false为不产生链接。 &l…

AI 绘画|Midjourney设计Logo提示词

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

R语言学习笔记8-并行计算

R语言学习笔记8-并行计算 简要说明使用parallel包使用foreach和doParallel包使用future包 简要说明 在R语言中&#xff0c;通过并行计算可以显著提升处理大数据集或执行耗时任务的效率。R提供了多种并行计算的方法&#xff0c;包括使用基础的parallel包和更高级的foreach和fut…

打包一个自己的Vivado IP核

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

知识加油站

我的&#x1f351;宝店【码猿小铺】持续进行&#xff0c;其中有Linux/shell视频&#xff08;包含项目实操&#xff09;、新版ShardingJDBC分库分表视频&#xff08;包含项目实操&#xff09;、初中高级面试专栏、React全套视频&#xff08;包含项目实操&#xff09;、新版javes…

【深度学习】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;受到了广泛关注。典型的研…

从MySQL迁移到PostgreSQL的完整指南

1.引言 在现代数据库管理中&#xff0c;选择合适的数据库系统对业务的成功至关重要。随着企业数据量的增长和对性能要求的提高&#xff0c;许多公司开始考虑从MySQL迁移到PostgreSQL。这一迁移的主要原因包括以下几个方面&#xff1a; 1.1 性能和扩展性 PostgreSQL以其高性能…

TCP/IP、UDP、HTTP 协议介绍比较和总结

TCP/IP、UDP、HTTP是网络通信中的三种重要协议,各自具有不同的特点和应用场景。以下是对这三种协议的详细介绍、比较和总结。 TCP/IP协议 传输控制协议/互联网协议(TCP/IP, Transmission Control Protocol/Internet Protocol) 特点: 可靠性:TCP提供可靠的通信,通过握手…

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

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

搜维尔科技:使用远程TCP和刀具路径遥操作点胶

使用远程TCP和刀具路径遥操作点胶 搜维尔科技&#xff1a;使用远程TCP和刀具路径遥操作点胶

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…

Linux C++ 056-设计模式之迭代器模式

Linux C 056-设计模式之迭代器模式 本节关键字&#xff1a;Linux、C、设计模式、迭代器模式 相关库函数&#xff1a; 概念 迭代器模式&#xff08;Iterator Pattern&#xff09;是一种常用的设计模式。迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素&#xff0c;而…

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

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

Bigdata-Docker构建大数据学习开发环境

Bigdata-Docker构建大数据学习开发环境 介绍 1、镜像环境 系统&#xff1a;centos 7Java &#xff1a;java7Zookeeper: 3.4.6Hadoop: 2.7.1mysql: 5.6.29Hive: 1.2.1Spark: 1.6.2Hbase: 1.1.2 2、镜像介绍 tonywell/centos-java&#xff1a;openssh、java7&#xff0c;基础…

示例:在WPF ListBox中,ScrollViewer.CanContentScroll=“False“破坏虚拟化如何解决

一、目的&#xff1a;分享一个解决ListBox设置了ScrollViewer.CanContentScroll"False"破坏虚拟坏的解决方法 ScrollViewer.CanContentScroll 是 WPF 中 ScrollViewer 控件的一个属性&#xff0c;它决定了滚动内容时是按逻辑单位&#xff08;如项&#xff09;还是按物…

redis基本类型和订阅

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