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://xiahunao.cn/news/3246380.html

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

相关文章

【前端7*】表格-表单2(弹窗在子组件)父子组件调用 vue element-ui

vue element-ui 中表单弹框的使用 写在最前面一、子组件 HelloWorld.vue1. 弹窗部分、将 visible 传值给父组件2.表单的 ruleForm 校验方法3.表单确认方法4. 提交确认方法&#xff1a;handleSummit5.表单渲染 二、父组件 HomeView.vue1.新增按钮、查看和编辑2.引用子组件弹窗3.…

强化学习——多臂老虎机问题(MAB)【附python代码】

文章目录 一、问题描述1.1 问题定义1.2 形式化描述1.3 累积懊悔1.4 估计期望奖励 二、解决方法2.1 ϵ-贪婪算法2.2 上置信界算法2.3 汤普森采样算法2.4 小结 一、问题描述 1.1 问题定义 有一个用于 K 根拉杆的老虎机&#xff0c;每一根拉杆都对应一个关于奖励的概率分布 R 。每…

Python项目实战之-爬取全网小说资源

python爬虫实战-小说爬取 基于requests模块与lxml模块编写的爬虫 基本思路 主要内容分为三个部分 使用requests模块获取网页内容使用lxml模块进行网页解析将解析出来的数据存储进MySQL数据库中 获取网页内容 网站分析 获取各个分类的href标签 代码如下 def novel_sort…

JMeter接口测试之文件上传(参数提取与传递)

参考文档&#xff1a; Jmeter接口测试-文件上传&#xff08;全网最详细的教程&#xff09;_jmeter 文件上传-CSDN博客 1、首先通过fiddler抓取文件上传接口&#xff0c;在Raw的tab页中查看默认请求头以及请求参数 如图所示 2、在jmeter中导入抓取的接口&#xff0c;首先需要配…

ctfshow~菜狗杯 损毁的压缩包

题目给了一个.zip的压缩包&#xff0c;解压报错 用010Editor打开看一下&#xff0c;发现文件头是png的 把文件后缀改成png看一下&#xff0c;得到flag ctfshow{e19efe2eb86f10ccd7ca362110903c05}

【生命游戏】python刷题记录

目录 题目&#xff1a; 代码&#xff1a; 结果&#xff1a; 总结&#xff1a; 题目&#xff1a; 代码&#xff1a; class Solution:def gameOfLife(self, board: List[List[int]]) -> None:"""Do not return anything, modify board in-place instead.&…

rocky9.3操作系统安装记录

文章目录 一、镜像源二、安装的过程选择安装过程中语言安装信息摘要页面设置安装目的地设置管理员密码调整网络开始部署 一、镜像源 Rocky-9.3-x86_64-minimal.iso 二、安装的过程 选择安装过程中语言 安装信息摘要页面 设置安装目的地 不做操作&#xff0c;直接使用自动分…

2.10、matlab中字符、数字、矩阵、字符串和元胞合并为字符串并将字符串以不同格式写入读出excel

1、前言 在 MATLAB 中&#xff0c;可以使用不同的数据类型&#xff08;字符、数字、矩阵、字符串和元胞&#xff09;合并为字符串&#xff0c;然后将字符串以不同格式写入 Excel 文件。 以下是一个示例代码&#xff0c;展示如何将不同数据类型合并为字符串&#xff0c;并以不…

LoadRunner12通过代理录制脚本。

1、目前LR12录制脚本比较简单的方式有两种&#xff0c;还有一种是失败率太高 我这边基本没有成功过就不赘述了&#xff0c;这边写的是通过LR的代理服务器来进行录制。 2、首选配置LR的录制界面点击录制按钮&#xff0c;会显示出录制配置界面 3、在录制配置界面录制模式选择’通…

【C++刷题】[UVA 489]Hangman Judge 刽子手游戏

题目描述 题目解析 这一题看似简单其实有很多坑&#xff0c;我也被卡了好久才ac。首先题目的意思是&#xff0c;输入回合数&#xff0c;一个答案单词&#xff0c;和一个猜测单词&#xff0c;如果猜测的单词里存在答案单词里的所有字母则判定为赢&#xff0c;如果有一个字母是答…

性能测试工具原理与架构

在性能测试的学习过程中&#xff0c;坚持思想与工具&#xff08;分开&#xff09;并行&#xff0c;当前面世面上的性能测试书籍大多把理论与loadrunner融为一体讲解&#xff0c;这样做是正确的&#xff0c;因为有一些性能名词概念也源于工具。但是&#xff0c;性能测试不是load…

生物安全柜验证:气流流型、粒子、浮游菌等参考标准

生物安全柜也是制药行业常见设备&#xff0c;根据GMP的要求&#xff0c;需对生物安全柜定期进行验证确认&#xff0c;确保生物安全柜的性能满足GMP洁净厂房的相关要求。 生物安全柜是实验室的基本设备&#xff0c;也是生物安全实验室的一级安全隔离屏障。其最重要的作用就是气流…

简过网:公务员面试考什么?抓紧时间收藏!

你知道吗&#xff1f;在公务员考试中&#xff0c;其实笔试不是最难的&#xff0c;难的是面试&#xff0c;那么&#xff0c;公务员的面试都考什么呢&#xff1f;这篇文章告诉你答案&#xff01; ​ 对于公务员的面试一般可分为三种形式&#xff1a; 一、无领导&#xff1a; 什…

Unity | Shader基础知识(第十八集:Stencil应用-透视立方盒子)

目录 一、前言 二、场景布置 三、 shader部分 1.图片的部分 2.图片部分纯净代码 3.遮罩部分复习 4.深度写入 ZWrite 5.颜色遮罩ColorMask 6.遮罩纯净代码 四、场景中shader使用 五、作者的碎碎念 一、前言 因为这个内容稍微有点多&#xff0c;我尽力讲清楚了&#x…

Windows安装Nacos【超详细图解】

目录 一、下载 Nacos 二、解压 Nacos 三、编辑配置文件 四、创建数据库 五、启动 Nacos 六、进入控制台 一、下载 Nacos Nacos v2.3.2 官方网址 二、解压 Nacos 三、编辑配置文件 主要修改数据库用户名、密码、鉴权是否开启、key value和token # # Copyright 1999-2021 …

Fiddler抓包过滤host及js、css等地址

1、如上图所示 在Filter页面中勾选Hide if URL contains&#xff1b;输入框输入 REGEX:\.(js|css|png|google|favicon\?.*) 隐藏掉包含js、css、png、google等的地址&#xff1a; Hide if URL contains: REGEX:\.(js|css|png|google|favicon\?.*) 2、使Filters设置生效 A…

用Python实现学生信息管理系统

用Python来实现学生信息管理系统 学生信息管理系统&#xff08;Python&#xff09; 简介&#xff1a;基本信息管理和学生成绩管理。基本信息管理模块的主要功能有学生信息的添加、删除、修改、显示和学生数据的导入导出&#xff0c;学生成绩管理模块的主要功能有统计课程最高分…

面向 AI 而生的香橙派 AIpro 开发板开箱实测

前几天搞到一块很牛掰的开发板&#xff0c;是香橙派联合华为精心打造的高性能 AI 开发板 – OrangePi AIpro 开发板。 其搭载了昇腾 AI 处理器&#xff0c;可提供 8TOPS INT8 的计算能力&#xff0c;作为单板硬件设备来说&#xff0c;算力杠杠的了&#xff0c;至于跑 AI 模型性…

liunx面试题目

如何看当前Linux系统有几颗物理CPU和每颗CPU的核数&#xff1f; 查看物理cup&#xff1a; cat /proc/cpuinfo|grep -c ‘physical id’ 查看每颗cup核数 cat /proc/cpuinfo|grep -c ‘processor’ 若希望自动实现软件包的更新&#xff0c;可以使用yum-cron并启动该服务 yum -y …

C++ :友元函数

什么是友元函数 外部函数访问类内成员 (1)写一个Person类&#xff0c;内部有private、protected、public的三类访问权限的成员 (2)写一个外部函数disp_info来打印这三类成员 (3)代码实战 (4)总结&#xff1a;可以访问public的&#xff0c;但是protected和private的无法访问 (5…