Spring AOP 的实现及原理

目录

  • 什么是 Spring AOP ?
    • AOP 是啥 ?
    • Spring AOP 可以干啥 ?
  • AOP 的组成
  • Spring AOP 的实现
  • Spring AOP 的实现原理

什么是 Spring AOP ?

AOP 是啥 ?

我们知道 OOP 是面向对象编程, 那 AOP 又是啥呢 ?

AOP(Aspect Oriented Programming):⾯向切⾯编程,它是⼀种思想,它是对某⼀类事情的集中处理。

什么又是面向切面编程?

就比如:我上 CSDN 发布文章时,它会先查询我的登录状态,我查询个人文章列表时,也要查询登录状态,查看个人主页也一样,这些功能的共同点是查询登录状态,那判断用户是否登录这件事,它就是一个切面,他就是某一类事,面向切面编程就是面向某一类事进行编程,将某一类事集中处理了。(这样就可以把精力放在业务逻辑上,而不是编写重复代码)

AOP 是⼀种思想,⽽ Spring AOP 是⼀个框架,提供了⼀种对 AOP 思想的实现,它们的关系和 IoC 与 DI 类似。

Spring AOP 可以干啥 ?

统一用户登录判断
统一日志记录
统一方法执⾏时间统计
统⼀的返回格式设置
统⼀的异常处理
事务的开启和提交等等

AOP 是针对某一类通用的事件进行统一处理,它是 OOP 的一种补充。

AOP 的组成

  1. 切面 (Aspect):定义的是什么事件(AOP 是干什么的,比如:是用户登录校验)

  2. 切点 (Pointcut):定义具体规则(定义用户拦截规则,比如:哪些接口需要判断用户登录,哪些接口不需要判断)

  3. 通知 (Advice):AOP 执行的具体方法(比如:获取用户登录信息,获取到则说明已登录)

通知又分为以下几种:
前置通知 @Before:通知⽅法会在⽬标⽅法调⽤之前执⾏。
后置通知 @After:通知⽅法会在⽬标⽅法返回或者抛出异常后调⽤。
返回通知 @AfterReturning:通知⽅法会在⽬标⽅法返回后调⽤。
异常通知 @AfterThrowing:通知⽅法会在⽬标⽅法抛出异常后调⽤。
环绕通知 @Around:通知包裹了被通知的⽅法,在被通知的⽅法通知之前和调⽤之后执行自定义的行为。

  1. 连接点 (Join Point):所有可能触发切点的点(比如:所有接口)

Spring AOP 的实现

  1. 添加 Spring AOP 依赖:
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-bo
ot-starter-aop -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
  1. 定义切面:
@Aspect  //表明此类为一个切面
@Component   // 随着spring框架启动而启动
public class UserAspect {}
  1. 定义切点:
@Aspect  //表明此类为一个切面
@Component   // 随着spring框架启动而启动
public class UserAspect {// 切点,这⾥使⽤ AspectJ 表达式语法//拦截 UserController 里所有方法@Pointcut("execution(* com.example.demo.controller.UserController.* (..))")public void pointcut(){   }
}
  1. 执行通知:

先将被拦截的类实现:

@RestController
@RequestMapping("/user")
public class UserController {@RequestMapping("/getuser")public String getUser() {System.out.println("do getUser");return "get User";}@RequestMapping("/deluser")public String delUser() {System.out.println("do delUser");return "del User";}
}
@Aspect  
@Component   
public class UserAspect {@Pointcut("execution(* com.example.demo.controller.UserController.* (..))")public void pointcut(){}//该前置通知针对于这个切点@Before("pointcut()")public void doBefore() {System.out.println("执行了前置通知");}
}

在这里插入图片描述
在这里插入图片描述
确实是先执行前置通知,再执行被拦截的方法。

再来执行个后置通知:

    @After("pointcut()")public void doAfter() {System.out.println("执行了后置通知");}

再次访问:
在这里插入图片描述
在这里插入图片描述

环绕通知:

    // 添加环绕通知@Around("pointcut()")public Object doAround(ProceedingJoinPoint joinPoint){Object obj = null;System.out.println("Around ⽅法开始执⾏");try {// 执⾏目标⽅法obj = joinPoint.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}System.out.println("Around ⽅法结束执⾏");return obj;}

在这里插入图片描述
在这里插入图片描述
环绕通知是在最前面和最后面执行的。(在多线程中可以统计目标方法的执行时间,单线程下也可以使用前置通知和后置通知来统计)

Spring AOP 的实现原理

Spring AOP 是构建在动态代理基础上,因此 Spring 对 AOP 的⽀持局限于⽅法级别的拦截。

Spring 动态代理组成:

  1. JDK Proxy(代理对象必须实现接口,才能使用 JDK Proxy)
  2. CGLIB(通过实现代理类的子类来实现动态代理,被 final 修饰的类不能被代理)

JDK Proxy 和 CGLIB 区别:

  1. 实现不同:DK Proxy 要求代理类实现接口才能被代理,CGLIB 通过实现代理类的子类来实现动态代理
  2. 性能不同:JDK 7+ JDK Proxy 的性能高于 CGLIB,JDK 7 前则低于

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

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

相关文章

Qml中double转int类型

在QML中&#xff0c;你可以使用JavaScript的内置函数将double类型转化为int类型。 1.去尾法&#xff1a;使用Math.floor()函数可以将一个double类型的数值向下取整为最接近的整数&#xff0c;Math.floor()将一个double类型的数值去尾转换为int类型。例&#xff1a; var doubl…

华为OD-非严格递增连续数字序列

题目描述 输入一个字符串仅包含大小写字母和数字 求字符串中包含的最长的非严格递增连续数字序列长度 比如&#xff1a; 12234属于非严格递增数字序列 输入描述 输入一个字符串仅包含大小写字母和数字 输出描述 输出字符串中包含的最长的非严格递增连续数字序列长度 示例…

适应高速率网络设备的-2.5G/5G/10G网络变压器/网络滤波器介绍

Hqst盈盛&#xff08;华强盛&#xff09;电子导读&#xff1a;在高速发展的互联网/物联网时代&#xff0c;为满足高网速的网络数据传输需求&#xff0c;网络设备在制造中也要选用合适的网络变压器/滤波器产品&#xff0c;有哪些可供选择的高速率网络变压器产品也是广大采购人员…

jvs-rules(规则引擎)更新:新增功能介绍

jvs-rules更新内容 1.复合变量新增数据补充节点&#xff0c;实现请求回来的数据再以入参方式请求其他数据进行数据补充&#xff08;例如通过参数A&#xff0c;请求回数据B&#xff0c;再以数据B为入参&#xff0c;请求回数据C&#xff09; 2.规则流结束节点支持新增、新建、引…

基于jeecg-boot的flowable流程跳转功能实现

更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/nbcio-boot 前端代码&#xff1a;https://gitee.com/nbacheng/nbcio-vue.git 在线演示&#xff08;包括H5&#xff09; &#xff1a; http://122.227.135.243:9888 今天我…

【Linux】权限

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析3 目录 &#x1f449;&#x1f3fb;shell命令解释器&#x1f449;&#x1f3fb;Linux用户…

【Java】【Stream流】分页

在Java开发中&#xff0c;使用Java自带Stream流的API来进行开发是一种常见的做法。 下面是一个简单的例子&#xff1a; 假设我们有一个包含100个数据项的列表。我们需要按照每页10个数据进行分页&#xff0c;并返回指定页码的数据。可以使用Java 8中的流来实现分页&#xff1…

使用 AutoGPTQ 和 transformers 让大语言模型更轻量化

大语言模型在理解和生成人类水平的文字方面所展现出的非凡能力&#xff0c;正在许多领域带来应用上的革新。然而&#xff0c;在消费级硬件上训练和部署大语言模型的需求也变得越来越难以满足。 &#x1f917; Hugging Face 的核心使命是 让优秀的机器学习普惠化 &#xff0c;而…

Mysql45讲学习笔记

前言&#xff1a;这篇文章主要总结事务&#xff0c;锁、索引的一些知识点&#xff0c;然后分享一下自己学习小心得&#xff0c;我会从点到线在到面展开说说&#xff0c;对于学习任何知识&#xff0c;我们都应该藐其全貌&#xff0c;不要一开始就选入细节 基础 一、基础架构&a…

基于ssm+vue德云社票务系统源码和论文

基于ssmvue德云社票务系统源码和论文063 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 1.选题的依据和意义 互联网时代&#xff0c;随着生活节奏的加快和不断上升的压力&#xff0c;人们急需寻找到情绪的宣泄…

docker第二次作业

1、使用mysql:5.6和 owncloud 镜像&#xff0c;构建一个个人网盘。 拉取镜像 docker pull mysql:5.6 docker pull ow ncloud 运行镜像生成容器 [rootharbor ~]# docker run -d --name mydb1 --env MYSQL_ROOT_PASSWORD123456 mysql:5.6 [rootharbor ~]# docker run -d --name…

Axure RP软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 Axure RP是Axure公司开发的一款原型设计工具&#xff0c;广泛应用于产品设计和UI/UX设计领域。以下是Axure RP软件的主要特点和功能&#xff1a; 原型设计&#xff1a;Axure RP提供了丰富的界面元素和交互元素&#xff0c;用户…

THINKPHP 微联云投票系统源码独立版 + 支持刷礼物

THINKPHP 微联云投票系统源码独立版 支持刷礼物 nginxphp7.2以上 mysql5.6以上 简单测试后台基本没什么问题&#xff0c;暂时发现H5前端有bug,自行修复。

VS2022 C++修改Window系统DNS源代码V2.0

这是自己使用VS2022 C++编写开发的Window系统下修改DNS脚本程序第2个版本,适合Win10系统和Win7系统。cfg.txt文件存放要修改的DNS,最多4个。 详细源代码如下: setdns.cpp /* 1.全部清空DNSstring strParameter;strParameter = "netsh interface ip delete dns name=\…

苹果新健康专利:利用 iPhone、Apple Watch 来分析佩戴者的呼吸情况

根据美国商标和专利局&#xff08;USPTO&#xff09;公示的清单&#xff0c;苹果获得了一项健康相关的技术专利&#xff0c;可以利用 iPhone、Apple Watch 来分析佩戴者的呼吸系统。 苹果在专利中概述了一种测量用户呼吸功能的系统&#xff0c;通过 iPhone 上的光学感测单元&am…

Linux Shell 搜索命令 grep

grep 是一个强大的文本搜索工具&#xff0c;用于在文件或标准输入中查找匹配指定模式的行。 它的基本语法是&#xff1a; grep [options] pattern [file...]其中&#xff0c;pattern 是要搜索的模式&#xff0c;可以是普通字符串或使用正则表达式表示的模式。file 是要被搜索…

6. 使用python将多个Excel文件合并到同一个excel-附代码解析

【目录】 文章目录 6. 使用python将多个Excel文件合并到同一个excel-附代码解析1. 目标任务2. 结果展示3. 代码示例4. 代码解析4.1 导入库4.2 调用库的类、函数、变量语法4.3 os.listdir-返回目录中的文件名列表4.4 startswith-用于判断一个字符串是否以指定的前缀开头4.5 ends…

Class ‘com.xxxx.Log‘ was compiled with an incompatible version of Kotlin.

Class com.xxxx.Log was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.7.1, expected version is 1.5.1. 原因&#xff1a;在build.gradle中使用了1.5.30版本的kotlin插件&#xff0c;与第三方库中的kotlin插件版本不同&#…

如何在Ubuntu 18.04上安装PHP 7.4并搭建本地开发环境

引言 PHP是一种流行的服务器脚本语言&#xff0c;用于创建动态和交互式web页面。开始使用你选择的语言是学习编程的第一步。 本教程将指导您在Ubuntu上安装PHP 7.4&#xff0c;并通过命令行设置本地编程环境。您还将安装依赖管理器Composer&#xff0c;并通过运行脚本来测试您…

React 使用 useRef() 获取循环中所有子组件实例

目录 背景思考实现完整代码&#xff1a;成功运行后的界面如下&#xff1a; 知识点总结uesRef() 作对象处理useImperativeHandle() 父组件操作引入子组件的内部方法最后 背景 之前项目中使用了antd pro 中的 可编辑表格 (EditableProTable)&#xff0c;在页面中表格要经过多层遍…