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.rhkb.cn/news/378475.html

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

相关文章

模块化和包管理工具

一&#xff0c;模块化 1.定义 将一个复杂的程序文件依据一定规则&#xff08;规范&#xff09;拆分成多个文件的过程称之为 模块化 其中拆分出的 每个文件就是一个模块 &#xff0c;模块的内部数据是私有的&#xff0c;不过模块可以暴露内部数据以便其他模块使用 2.模块化…

【React Hooks原理 - forwardRef、useImperativeHandle】

概述 上文我们聊了useRef的使用和实现&#xff0c;主要两个用途&#xff1a;1、用于持久化保存 2、用于绑定dom。 但是有时候我们需要在父组件中访问子组件的dom或者属性/方法&#xff0c;而React中默认是不允许父组件直接访问子组件的dom的&#xff0c;这时候就可以通过forwa…

如何通过网络快速搜寻到自己的STM32设备

目录 一、问题概述 二、解决思路 三、代码实现 1.创建任务 2.UDP广播接收 一、问题概述 以前一直用RS232串口修改设备配置信息&#xff0c;但是现场施工人员的232线太细&#xff0c;经常容易断掉&#xff0c;这次准备用网口去修改&#xff0c;遇到了一个问题&#xff0c;…

【简历】惠州某二本学院:前端简历指导,秋招面试通过率为0

注&#xff1a;为保证用户信息安全&#xff0c;姓名和学校等信息已经进行同层次变更&#xff0c;内容部分细节也进行了部分隐藏 简历说明 这是一份25届二本同学&#xff0c;投递前端职位的简历&#xff0c;那么在校招环节二本同学主要针对的还是小公司&#xff0c;这个学校因为…

【B树、B-树、B+、B*树】

目录 一、B-树&#xff08;即B树&#xff09;的定义及操作1.1、定义1.2、操作1.2.1、查找1.2.2、插入1.2.3、删除 二、B树的定义及操作2.1、定义2.2、操作2.2.1、查找2.2.2、插入2.2.3、删除 三、B*树 一、B-树&#xff08;即B树&#xff09;的定义及操作 1.1、定义 B-tree即…

18_Shell好用工具:sort

18_Shell好用工具&#xff1a;sort 选项说明-k指定要排序的列-nnumber&#xff0c;按照数值大小排序-rreverse&#xff0c;逆序-t分隔符-u去重-o保存排序到文件 一、数字升序 #sort1.txt文件纯数字 #升序 sort -n sort1.txt #降序 sort -nr sort1.txt二、数字升序去重 #数字…

框架设计MVC

重点&#xff1a; 1.用户通过界面操作&#xff0c;传输到control&#xff0c;control可以直接去处理View&#xff0c;或者通过模型处理业务逻辑&#xff0c;然后将数据传输给view。 2.control包含了model和view成员。 链接&#xff1a; MVC框架详解_mvc架构-CSDN博客 MVC架…

C语言------指针讲解(2)

目录 一、数组名的理解 二、使用指针访问数组 三、一维数组传参的本质 四、冒泡排序 五、二级指针 六、指针数组 七、指针数组模拟二维数组 一、数组名的理解 通过学习&#xff0c;我们知道&#xff1a;数组名和数组首元素的地址打印出来的结果一模一样&#xff0c;数组…

【STM32】RTT-Studio中HAL库开发教程三:IIC通信--AHT20

文章目录 一、I2C总线通信协议二、AHT20传感器介绍三、STM32CubeMX配置硬件IIC四、RTT中初始化配置五、具体实现代码六、实验现象 一、I2C总线通信协议 使用奥松的AHT20温湿度传感器&#xff0c;对环境温湿度进行采集。AHT20采用的是IIC进行通信&#xff0c;可以使用硬件IIC或…

顺序表的应用——通讯录

通讯录的实现分为五个文件分别进行编写&#xff0c;分别为&#xff1a;SeqList.c&#xff0c;SeqList.h&#xff0c;Contact.c&#xff0c;Contact.h&#xff0c;test.c 其中前两个文件为上一篇博客中的顺序表的操作&#xff0c;后三个文件为通讯录功能的实现。 SeqList.h #d…

jenkins系列-07.轻易级jpom安装

jpom是一个容器化服务管理工具&#xff1a;在线构建&#xff0c;自动部署&#xff0c;日常运维, 比jenkins轻量多了。 本篇介绍mac m1安装jpom: #下载&#xff1a;https://jpom.top/pages/all-downloads/ 解压&#xff1a;/Users/jelex/Documents/work/jpom-2.10.40 启动前修…

Ubuntu上安装配置samba服务

Ubuntu上安装配置samba服务 在Ubuntu中安装配置samba共享服务&#xff0c;可以让你在网络上共享文件和打印机。以下是一个相对详细的步骤指南&#xff0c;介绍如何在Ubuntu上安装和配置Samba。 1. 安装Samba 首先&#xff0c;需要安装Samba软件包。打开终端并运行以下命令&a…

在SpringCloud中如何轻松实现微服务间的通信

在Spring Cloud中&#xff0c;实现微服务间的通信非常简单。Spring Cloud提供了多种方式来进行微服务之间的通信&#xff0c;包括使用RestTemplate、Feign、Ribbon、Eureka等组件。下面我将详细介绍这些方式的使用方法。 使用RestTemplate进行通信&#xff1a; RestTemplate是S…

Qt 多语言

记录Qt多语言的实现过程 目录 1.项目配置文件.pro配置 2.程序中的字符串用tr()封装 3.生成翻译文件 4.使用Qt语言家修改翻译文件 4.1使用Qt语言家打开 4.2 .更改文件配置 5. 生成qm文件 6.代码执行切换语言 6.1入口处 6.2 事件执行 0.效果 1.项目配置文件.pro配置 T…

2024年【天津市安全员C证】免费试题及天津市安全员C证考试技巧

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 天津市安全员C证免费试题根据新天津市安全员C证考试大纲要求&#xff0c;安全生产模拟考试一点通将天津市安全员C证模拟考试试题进行汇编&#xff0c;组成一套天津市安全员C证全真模拟考试试题&#xff0c;学员可通过…

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

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

docker安装nginx并配置https

参考 docker安装nginx并配置https-腾讯云开发者社区-腾讯云 (tencent.com) 证书的生成 参见&#xff1a;SpringBoot项目配置HTTPS接口的安全访问&#xff08;openssl配置&#xff09;_配置接口访问-CSDN博客 步骤 1: 拉取Nginx镜像 docker pull nginx 好使的镜像如下&#x…

「漏洞复现」同享人力资源管理系统-TXEHR V15 DownloadTemplate 文件读取漏洞

0x01 免责声明 请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;作者不为此承担任何责任。工具来自网络&#xff0c;安全性自测&#xff0c;如有侵权请联系删…

权威认可 | 海云安开发者安全助手系统通过信通院支撑产品功能认证并荣获信通院2024年数据安全体系建设优秀案例

近日&#xff0c;2024全球数字经济大会——数字安全生态建设专题论坛&#xff08;以下简称“论坛”&#xff09;在京成功举办。由全球数字经济大会组委会主办&#xff0c;中国信息通信研究院及公安部第三研究所共同承办&#xff0c;论坛邀请多位专家和企业共同参与。 会上颁发…

Python JSON处理:兼容性与高级应用

JSON&#xff08;JavaScript Object Notation&#xff09;作为当前最流行的数据传输格式&#xff0c;在Python中也有多种实现方式。由于JSON的跨平台性和简便易用性&#xff0c;它在数据交互中被广泛应用。本文将重点讨论如何熟练应用Python的JSON库&#xff0c;将JSON数据映射…