当前位置: 首页 > news >正文

Spring挖掘:(AOP篇)

学习AOP时,我们首先来了解一下何为AOP

一. 概念

AOP(面向切面编程,Aspect Oriented Programming)是一种编程技术,旨在通过预编译方式或运行期动态代理实现程序功能的统一管理和增强。AOP的主要目标是在不改变原有业务逻辑代码的基础上,添加或修改非核心业务逻辑,如日志记录、性能监控、安全检查等。这种方式有助于减少代码重复,提高代码的模块化程度,降低系统组件间的耦合度,进而提升软件的可维护性和可扩展性。

AOP的核心概念包括:

切面(Aspect):切面是关注点的模块化,它横切多个对象。例如,事务管理就是一个典型的切面。

连接点(Join Point):程序执行过程中的某个点,如方法调用或异常抛出。AOP框架会在这个点上应用切面。

通知(Advice):切面在特定的连接点上执行的动作。根据调用时机不同,通知分为前置通知、后置通知、环绕通知等。

切入点(Pointcut):定义了通知应该应用于哪些连接点的规则。它是切面的一个组成部分。

用图来表示

注意的是:所有方法都是一个连接点,而我们需要增强的就是一个切入点

二. 底层

AOP其实是基于代理模式来实现的.而在Java当中,分为静态代理和动态代理两种模式.

简单描述一下静态代理,着重表示一下动态代理.

2.1 静态代理

静态代理: 你可以理解为就是硬编码, 例如现在一个计算器类,分别有加减乘除功能.而此时你想增强这些方法,例如在这些方法上面添加一些日志,那静态代理的实现就是创建一个新的类,聚合一下这个计算器类,也实现计算器类实现的接口,也就是加减乘除. 去实现具体的加减乘除时还是调用原本计算器类的方法,只是在调用这个方法前后可以书写你要增加的逻辑.

2.2 动态代理

在动态代理当中我们分为两种代理方式.

2.2.1 JDK动态代理

JDK的代理是基于接口实现的.如果一个类没有实现接口,是不可以使用JDK的动态代理的.

2.2.1.1 演示

我通过一个火车站售票的一个场景来演示一下动态代理是怎么实现的.

创建一个售票的接口,里面有两个方法,一个售票,一个打印

创建一个火车站类,实现这个接口

在JDK中,我们可以调用Proxy.newProxyInstance()方法来获取一个代理对象.

  • 第一个参数为加载当前需要代理的类的类加载器,
  • 第二个参数为需要代理的类的实现的接口(这也就证明是基于接口来实现的)
  • 第三个参数需要一个实现InvocationHandler接口的类,可以用匿名内部类来实现,这一块也就是用来增加逻辑的一块.

我们创建一个代理工厂的类来实现这段逻辑

测试类

测试结果

2.2.2 CGLIB动态代理

CGLIB是可以基于接口也可以基于类实现的.

2.2.2.1 演示

还是买票这个例子,只不过我们换种实现.

而使用CGLIB代理时,我们需要去实现MethodInterceptor接口,创建代理对象时,需要使用CGLIB提供的Enhance类来实现.

这里使用了三个方法.

setInterfaces与setSuperclass通过方法名我们知道,是用来设置代理类的接口与父类.侧面也证实了CGLIB是可以基于接口和类实现的.

而setCallback的作用是设置回调对象,回调对象在CGLIB生成的代理对象中用于处理方法调用。具体来说:

  • 当通过代理对象调用方法时,CGLIB会拦截该方法调用,并将控制权交给回调对象。
  • 回调对象可以对方法调用进行增强处理,如添加日志、事务管理、权限检查等。
  • 在这个例子中,回调对象被设置为当前对象(this),意味着当前对象需要实现CGLIB的回调接口(如MethodInterceptor),以便在方法调用时执行特定的逻辑.

所以这就是为什么需要实现MethodInterceptor方法.

测试类

测试结果

我们尝试将Transtaion实现的接口不实现,看能否代理成功

测试类

测试结果

我们清晰看到代理没有任何问题,也是通过代理对象调用的.

二. AOP实战演练

我们简单书写一个计算机的工具类

现在我们来书写一个AOP切面类.

介绍一下这里使用到的几个重要注解的作用

  • @Aspect(切面类): 声明此类为一个AOP切面类,需要扫描方法上Before等注解
  • @PointCut(切入点): 切入点表达式,选取对应的连接点来作为切入点
    • execution: 切入点表达式,以 返回值 + [全限类名] + 方法名(参数类型),* 指代任意类型
  • @Before(前置通知): 方法调用前执行
  • @After(后置通知): 方法调用后执行
  • @AfterThrowing(异常后通知): 方法执行时发生异常执行
  • @AfterReturning(方法返回后通知): 方法能正确返回值执行.

他们的调度过程可以用一张图来表示

我们执行测试类来查看测试结果

这里有两个细节

  • 第一个表明了AOP拦截的执行顺序为前置,返回(无异常时),后置
  • 第二个表明,我们查看到实际上执行对应方法的是代理对象,而更注意的是SpringBoot的底层使用的是CGLIB代理.但实际上我们还看到一个执行对象就是我们具体的实现CaculatorImpl,这两个是不一样的,在使用add方法的入口时,使用的是AOP代理对象,而实际去执行方法时,还是调用我们实现的CaculatorImpl去实现的.

这就是我们基于Spring AOP来简单实现了一下如何应用.

那么复杂一点的情形,现在有两个切面类同时应用到了同一个方法,那么又会是怎么样的情形呢?

我们再书写一个权限的切面类,来查看会有什么现象产生

同样启动我们的测试实例,来查看效果

我们观察到执行顺序如下面这一张图来表示

所以我们了解到有AOP嵌套时的,执行顺序会变成这样的流程,会把另一个AOP的过程当成整体作为执行流程.

还有一个情形,就是当我们使用环绕通知时,我们是可以利用环绕通知模拟这四个情形,我们修改我们原来日志的代码

利用环绕通知来模拟四种情形,启动一下测试

至此AOP基本功能我们都测试完毕,还有一种情形我们一直没有探究,当我们执行时出现异常时,AOP的执行流程是什么样子的呢?

测试结果为 前置 -> 执行 -> 异常 -> 后置

那我们再开启一下我们之前的权限AOP,我们捕获了异常,此时会发生什么现象呢?(由于异常日志太多,我这里捕获异常就不打印啦)

在权限这里,我们发现他并没有走异常处理的增强,执行流程为下方图示这样

所以,我们通常建议环绕通知时,捕获异常后,继续往上抛出异常,让其他的AOP对象感知到异常的存在,执行对应的异常处理.

相关文章:

Spring挖掘:(AOP篇)

学习AOP时,我们首先来了解一下何为AOP 一. 概念 AOP(面向切面编程,Aspect Oriented Programming)是一种编程技术,旨在通过预编译方式或运行期动态代理实现程序功能的统一管理和增强。AOP的主要目标是在不改变原有业务逻辑代码的…...

十四届蓝桥杯STEMA考试Python真题试卷第二套第四题

来源:十四届蓝桥杯STEMA考试Python真题试卷第二套编程第四题:糖果罐调整 该题解通过贪心策略在每一步都选择对当前状态最有利的操作,从而达到最少调整次数的目标。 题目描述 现有 N 罐糖果,且已知每罐糖果的初始数量。现给出两个数值 L 和 R(L≤R),需要把每罐糖果的数…...

单元测试怎么做

单元测试是软件开发中非常重要的一部分,能够确保代码的正确性、可靠性和可维护性。对于 Vue 项目来说,单元测试主要关注的是测试组件及其相关功能是否正常。下面是如何在 Vue 项目中进行单元测试的详细步骤,包括测试框架的选择、测试工具的配…...

移动应用开发 实验二:标准身高计算器

文章目录 准备工作一,创建Android Studio项目二,创建活动模块三,设计用户界面(一)设置页面布局(二)添加标题文本控件(三)设计体重输入框(四)设计性…...

金华迪加现场大屏互动系统 mobile.do.php 任意文件上传漏洞复现

0x01 产品描述: ‌ 金华迪加现场大屏互动系统‌是由金华迪加网络科技有限公司开发的一款专注于增强活动现场互动性的系统。该系统设计用于提供高质量的现场互动体验,支持各种大型活动,如企业年会、产品发布会、展览展示等。其主要功能包…...

使用 pd.ExcelWriter 创建多工作表 Excel 文件的详细教程

with pd.ExcelWriter(...) as writer 可以将多个内容写入一个 Excel 文件中。具体地说,它创建了一个Excel 文件写入器,使得我们可以在一个文件中创建多个工作表(Sheet)。 with pd.ExcelWriter("模型指标和损失值.xlsx")…...

驱动-----dht11温湿度传感器

单总线:只用一根线。 复位信号:设置为输出模式,低电平20ms,然后再拉高30us。然后设置为输入模式,dht11会先拉低80us,然后拉高80us表示对接成功 数据0:开始先拉低50us,然后拉高26~28u…...

Docker 基础命令简介

目录 Docker 基础命令 1. Docker 版本信息 2. 获取 Docker 帮助 3. 列出所有运行中的容器 4. 运行一个新的容器 5. 查看容器日志 6. 停止容器 7. 启动已停止的容器 8. 删除容器 9. 列出所有镜像 10. 拉取镜像 11. 构建镜像 12. 删除镜像 13. 执行命令 14. 查看容…...

嵌入式开发之静态库和共享库

静态库 静态库的特点: 默认执行库链接的时候,检索的是Linux的/lib、/usr/lib目录下,如果指定gcc -c .... -L 指定路径 -l指定库文件;c语言分为预编译、编译、汇编、链接四个步骤。链接的时候是把依赖库文件函数的代码拷贝到程序里面,即便是删除库文件。拷贝后的程序依旧…...

关于npm源的切换及相关操作

要查看当前配置的 npm 源(registry),可以使用以下命令: 查看 npm 源 npm config get registry这个命令会返回目前被设置的 npm registry URL,通常情况下是 https://registry.npmjs.org/。 列出所有 npm 配置项 如果…...

vue前端sku实现

this.value.skuStockList [];let skuList this.value.skuStockList;//只有一个属性时if (this.selectProductAttr.length 1) {let attr this.selectProductAttr[0];for (let i 0; i < attr.values.length; i) {skuList.push({spData: JSON.stringify([{key:attr.name,v…...

使用Vue3和Vue2进行开发的区别

使用Vue3和Vue2进行开发的区别 笔者虽然老早就是用vue3进行开发了&#xff0c;但是上次有人问道使用vue3进行开发跟使用vue2进行开发的区别有哪些这个问题的时候&#xff0c;回答的还是有些琐碎&#xff0c;干脆今天专门整理一下&#xff0c;做个记录。 一、再也不用set了 众所…...

爬虫入门urllib 和 request(二)

文章目录 1、urllib介绍2、urllib的基本方法介绍2.1 urllib.Request2.2 response.read() 3、urllib请求百度首页的完整例子4、小结 1、urllib介绍 除了requests模块可以发送请求之外, urllib模块也可以实现请求的发送,只是操作方法略有不同! urllib在python中分为urllib和url…...

【大数据学习 | HBASE】hbase的整体架构

hbase的region存储原理图 首先我们看到hbase的组成分为两个大的部分&#xff0c;分别是hmaster和hregionserver&#xff0c;主节点用于协调数据&#xff0c;regionserver用于真正的去管理表&#xff0c;其中regionserver存在多个&#xff0c;他们共同协调管理全有的表&#xff…...

群控系统服务端开发模式-应用开发-个人资料

群控系统服务端开发模式后端基础框架现在就差个人资料、及权限验证。下面开发个人资料。 一、获取个人信息 1、添加路由 在根目录下route文件夹下面app.php文件中添加如下代码&#xff1a; Route::post(member/personal_data,permission.Member/personalData);// 获取个人信息…...

openssl生成加密,公钥实现非对称加密

私钥用于加密&#xff0c;公钥用于解密 私钥用于颁发token&#xff0c;公钥用于验证token&#xff0c;公钥不能颁发token 私钥和公钥是一对&#xff0c;不能单独使用&#xff0c;利用私钥生成公钥&#xff0c;利用公钥进行解密 使用openssl来生成一对私钥和公钥&#xff1a;ope…...

[CKS] K8S Admission Set Up

最近准备花一周的时间准备CKS考试&#xff0c;在准备考试中发现有一个题目关于Admission。 Whats Admission Kubernetes Admission是Kubernetes集群中一种机制&#xff0c;用于控制和修改集群中的资源对象。它允许您在Kubernetes资源被创建、更新或删除之前&#xff0c;对资源…...

前端学习Day13 CSS盒子的定位(固定定位篇“附练习”)

一、固定定位 固定定位 &#xff08;position:fixed&#xff09;其实是绝对定位的子类别&#xff0c;一个设置了 position:fixed 的元素是相对于视窗固定的&#xff0c;就算页面文档发生了滚动&#xff0c;它也会一直待在相同的地方。 ⚠️&#xff1a;固定定位会脱离文档流。…...

Tomcat 启动卡住,日志显示 At least one JAR was scanned for TLDs yet contained no TLDs.

现象 Tomcat 启动后&#xff0c;控制台输出卡在了&#xff1a; At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JA…...

计算机网络:网络层 —— 移动 IP 技术

文章目录 IPv6IPv6 的诞生背景主要优势IPv6引进的主要变化 IPv6数据报的基本首部IPv6数据报首部与IPv4数据报首部的对比 IPv6数据报的拓展首部IPv6地址IPv6地址空间大小IPv6地址的表示方法 IPv6地址的分类从IPv4向IPv6过渡使用双协议栈使用隧道技术 网际控制报文协议 ICMPv6ICM…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

Go语言多线程问题

打印零与奇偶数&#xff08;leetcode 1116&#xff09; 方法1&#xff1a;使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...