Spring AOP源码分析
#### AOP(面向切面编程)作用及其优势 作用:在程序运行期间,在不修改源码的情况下对方法进行功能增强(通知) 优势:减少重复代码,提高代码复用性,提高代码可维护性,提高代码可扩展性 #### AOP的底层实现原理 动态代理:JDK动态代理 【基于接口的动态代理技术】(基于反射)、CGLIB动态代理【基于父类的动态代理技术】 实际上,AOP的底层是通过Spring提供的动态代理技术实现的。在运行期间,Spring通过动态代理技术动态生成代理对象,代理对象方法执行时进行增强功能(通知)的介入,再去调用目标对象的方法(系统功能),从而完成功能的增强。 + JDK动态代理:要实现InvocationHandler接口(java.lang.reflect.InvocationHandler),重写invoke方法,通过Proxy.newProxyInstance()方法创建代理对象。(反射) + Cglib动态代理:要实现MethodInterceptor接口(org.springframework.cglib.proxy.MethodInterceptor),重写intercept方法,通过Enhancer.create()方法创建代理对象 // 可以在启动时,设置保存生成的代理类文件 System.getProperties().put( "sun.misc.ProxyGenerator.saveGeneratedFiles" , "true" ); #### AOP的相关概念 + Target:目标对象,被代理的对象 + Proxy:代理对象,代理目标对象 + Joinpoint:连接点,目标对象中可以被增强的方法 + Pointcut:切入点,被增强的方法集合(对哪些Joinpoint进行拦截的定义) + Advice:通知,增强的代码(拦截到Joinpoint后要执行的代码) + Aspect:切面,切入点+通知 + Weaving:织入,将通知应用到目标对象并创建代理对象的过程 #### AOP源码解析 1.须知: -.在使用ApplicationContentext相关实现类加载ben的时候,会针对所有单例且非懒加载的bean,在构造ApplicationContext的时候就会创建好这些bean,而不会 等到使用的时候才会创建。这也就是单例bean默认非懒加载的应用。 -.读者需要了解BeanPostProcessor接口,这个接口是Spring提供的一个扩展接口,用于在bean初始化前后做一些处理工作。 - 结合以上两点,被代理后的bean,实际在ApplicationContext构造完成之后就已经被创建完成,getBean()的操作直接从singletonObjects中获取即可。 2. 注册自动代理创建器 - 但凡注解都有对应的解析器,以用来解析该注解的行为。而且所有的解析器父类为:NamespaceHandlerSupport,这个类是用来解析xml配置文件的。(可以通过调用链查看) - 解析xml配置文件的时候,会调用NamespaceHandlerSupport的init()方法,这个方法会调用registerBeanDefinitionParser()方法,这个方法会将解析器注册到一个map中。 - Spring中将标签分为两大类:default(默认)和custom(拓展) default namespace 涉及到的只有四个标签:import、alias、bean、beans 【使用方法parseDefaultElement(ele,delegate)】 custom namespace 涉及到的标签:mvc、task、context、aop等 - 以aop为例,解析器为AopNamespaceHandler,解析器会调用registerBeanDefinitionParser()方法,将解析器(AspectJAutoProxyBeanDefinitionParser)注册到一个map中。AspectJAutoProxyBeanDefinitionParser实现了BeanDefinitionParser接口,重写了parse()方法,这个方法会调用registerAutoProxyCreatorIfNecessary()方法【将AnnotationAwareAspectJAutoProxyCreator注册到Spring容器中,把bean交给spring去托管】 - 查看AnnotationAwareAspectJAutoProxyCreator的类层次结构,可知其父类为AbstractAutoProxyCreator,这个类实现了BeanPostProcessor接口,重写了postProcessAfterInitialization()方法(模板方法) - 通过调用链查看,AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization()方法会调用wrapIfNecessary()方法,这个方法会调用createProxy()方法(将所有有Advice的bean重新包装成proxy) 3. 执行逻辑:代理对象创建好后,其拦截方法的操作都是交给Methodinvocation去做,JdkDynamicAopProxy交给ReflectiveMethodInvocation,ObjenesisCglibAopProxy交给CglibMethodInvocation. 类的继承关系(父->子)前面三个都是aopalliance下的 Joinpoint->Invocation->MethodInvocation(org.aopalliance.intercepet.MethodInvocation)->ProxyMethodInvocation->ReflectiveMethodInvocation->CglibMethodInvocation 这里说明一下JdkDunamicAopProxy的proceed()[继承自JoinPoint,执行链执行]方法 //这里是JdkDynamicAopProxy的执行的核心,要执行方法,执行通知都在这里搞定[递归调用,执行所有过滤器链的逻辑] ``` @Override @Nullable public Object proceed() throws Throwable {//this.currentInterceptorIndex初始值为-1,如果执行到执行链的末尾,则直接调用连接点方法(即目标方法)if(this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMathers,size() -1){//该方法内部逻辑调用目标方法return invokeJoinponit();}//获取集合中的MethodInterceptor,执行链索引加1(这里的+1保证是递归调用而不是循环调用)Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMathers.get(++this.currentInterceptorIndex);//InterceptorAndDynamicMethodMacher有两个属性MethodInterceptor,MethodMatcher,看看在advisor chain是否能够匹配上if(interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMacher){InterceptorAndDynamicMethodMacher dm = (InterceptorAndDynamicMethodMacher) interceptorOrInterceptionAdvice;//判断拦截器是否适用这个目标方法,是 执行这个拦截器 否 跳过这个拦截器进入下一个拦截器if(dm.methodMatcher.matches(this.method,this.targetClass,this.arguments)){//拦截器的内部,除自己逻辑外,也会有mi.proceed()保证执行到下一个拦截器return dm.interceptor.invoke(this);}else{return proceed();}}else {//MethodInterceptor直接执行(只有匹配上的方法才会在拦截器链中)return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);} } ```
相关文章:
Spring AOP源码分析
#### AOP(面向切面编程)作用及其优势 作用:在程序运行期间,在不修改源码的情况下对方法进行功能增强(通知) 优势:减少重复代码,提高代码复用性,提高代码可维护性…...

[LLM]从GPT-4o原理到下一代人机交互技术
一 定义 GPT-4o作为OpenAI推出的一款多模态大型语言模型,代表了这一交互技术的重要发展方向。 GPT-4o是OpenAI推出的最新旗舰级人工智能模型,它是GPT系列的一个重要升级,其中的"o"代表"Omni",中文意思是“全…...
【Spring】AOP——通知(Advice)
1、通知(Advice) 1.1简介 在AOP中,通知(Advice)是切面(Aspect)中的一部分,用于定义在连接点(Joinpoint)处应该执行的操作。通知类型可以在AOP框架中配置和使…...
python中的一些基础概念
在python中整型数据可以和浮点型数据相加,在python中字符串数据可以进行相加, 在python中整型数据可以和布尔类型进行算术运算。此时True当做1,False当做0但是这样的操作是没有意义的, python中只有字符串类型没有字符类型&…...

8.Redis之hash类型
1.hash类型的基本介绍 哈希表[之前学过的所有数据结构中,最最重要的] 1.日常开发中,出场频率非常高. 2.面试中,非常重要的考点, Redis 自身已经是键值对结构了Redis 自身的键值对就是通过 哈希 的方式来组织的 把 key 这一层组织完成之后, 到了 value 这一层~~ value 的其中…...
Edge浏览器
微软 Edge 是由微软开发的网络浏览器,它是 Windows 10 操作系统的默认浏览器,取代了之前的 Internet Explorer。Edge 浏览器在设计上注重性能、安全性和易用性,同时也提供了许多实用的功能,如内置笔记、阅读视图、集成的语音助手等…...

springboot项目中图片上传之后需要重启工程才能看到图片?
需求背景 最近在做一个用户自定义上传头像的小需求,用户上传头像然后需要立马回显。 需求是很常见的、正当的需求。如果不使用到对象存储这类服务,我们把用户头像的图片文件仅存在本地就可以了。我们在开发的过程中为了工程管理方便通常下意识会将图片…...

打卡信奥刷题(20)用Scratch图形化工具信奥B3756 [信息与未来 2021] 幸运数字
本题的基础是进制转换,关于2进制转换可以参考打卡信奥刷题(19)用Scratch图形化工具信奥B3972 [语言月赛 202405] 二进制 题解 知道了2进制,来实现5进制、7进制、9进制是一样的。 [信息与未来 2021] 幸运数字 题目描述 如果⼀个…...

Stream流模式通信及示例
Stream流模式通信是指在计算机网络中,数据作为连续的字节流传输而不是独立的数据包。它是一种面向连接的通信方式,常见于TCP(传输控制协议)。以下是Stream流模式通信的基本概念和一个简单的示例。 基本概念 面向连接࿱…...

从0开始学统计-t分布
1.t分布是如何被发现的? t分布最早由英国统计学家威廉塞弗顿(William Sealy Gosset)在1908年提出。塞弗顿是爱尔兰的一名酿酒厂的统计学家,他的工作需要对小样本数据进行分析。由于当时样本量较小(通常小于30…...

Git总结超全版
最近想系统的回顾一下Git的使用,如果只想快速的集成git到idea,可以参考另一篇我的博客中的git部分 目录 版本管理工具简介Git安装与配置Git远程仓库配置 Git常用命令为常用命令配置别名(可选)Git忽略文件.gitignore一些概念*本地仓库操作删除仓库内容 *远…...

网络安全之安全协议浅谈
安全协议 安全协议概述安全协议分类IPSecIPSec安全协议IPSec架构IPSec封装模式AH协议ESP协议SET协议SET协议电子交易模型SET协议安全目标认证中心CA 安全协议概述 安全协议是信息交换安全的核心,它在网络不同层次上、针对不同应用,通过对各种密码学技术…...
华为云部署前端项目发生的事
今天刚买了一个云服务,想着部署一下前端项目: 使用的是 docker nginx 部署 部署方法,在以往的文章中有介绍,如有兴趣可以看看docker 部署; 结果发现部署成功之后,竟然无法访问,从命令来看&…...
需求:实现一个可以统计代码的运行时间
需求:有一个做加法计算的函数,要统计执行这个加法函数代码运行了多久 import timedef add(a, b):time.sleep(1)return a bst time.time() add(100, 200) et time.time() print("该函数运行时间为:", et - st) 学了闭包&#x…...
软考高级之redis中使用zset实现延迟队列,你答对了么?
实现延迟队列的思路 zset的特性,带有分数的排序,以时间戳作为分数进行排序 添加任务 zdd取出任务 zrangbyscore执行任务 zrem 定时任务 public static void main(String[] args) {Jedis jedis new Jedis("ip", 6379);TimerTask task new …...

CS 下载安装详解
目录 CS简介: CS下载地址: CS的安装: CS简介: CS为目前渗透中常用的一款工具,它的强大在于控制windows木马,CS主要控制windows木马。 CS下载地址: 链接:https://pan.baidu.com/…...
前端canvas项目实战——在线图文编辑器(十):小地图MiniMap(上)
目录 前言一、 效果展示二、 实现步骤0. 行动前的思考1. 为小地图更新「背景图」2. 为小地图更新「滑动窗口」2.1 获取新的滑动窗口「宽高」2.2 获取新的滑动窗口「位置」3. 为小地图更新「遮罩」后记前言 上一篇博文中,我们引入了「逻辑画布」的概念,让整个工具的页面看起来…...
linux的chmod的数字太难记了,用u, g, o, a更简单!
u, g, o, 和 a是用来设置或查看文件或目录权限在类Unix或Linux系统中的特殊字符,它们分别代表文件或目录的所有者(user)、所属组(group)、其他用户(others)和所有用户(all users)。 而权限方r和w是其中的两种,分别代表读权限(read࿰…...

牛客热题:有效括号
📟作者主页:慢热的陕西人 🌴专栏链接:力扣刷题日记 📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言 文章目录 牛客热题:有效括号题目链接方法一&#x…...
利用SQL语句实现多表联合查询——多表关系介绍
1.多对多查询 先创建一个student表和course表,应该利用外键来实现,通过一个中间表分别对应student和course中的id CREATE TABLE student (id INT unsigned PRIMARY KEY,name VARCHAR(255),no VARCHAR(50) ); CREATE TABLE course (id INT PRIMARY KEY,…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...

【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
【深尚想】TPS54618CQRTERQ1汽车级同步降压转换器电源芯片全面解析
1. 元器件定义与技术特点 TPS54618CQRTERQ1 是德州仪器(TI)推出的一款 汽车级同步降压转换器(DC-DC开关稳压器),属于高性能电源管理芯片。核心特性包括: 输入电压范围:2.95V–6V,输…...
iOS 项目怎么构建稳定性保障机制?一次系统性防错经验分享(含 KeyMob 工具应用)
崩溃、内存飙升、后台任务未释放、页面卡顿、日志丢失——稳定性问题,不一定会立刻崩,但一旦积累,就是“上线后救不回来的代价”。 稳定性保障不是某个工具的功能,而是一套贯穿开发、测试、上线全流程的“观测分析防范”机制。 …...

java 局域网 rtsp 取流 WebSocket 推送到前端显示 低延迟
众所周知 摄像头取流推流显示前端延迟大 传统方法是服务器取摄像头的rtsp流 然后客户端连服务器 中转多了,延迟一定不小。 假设相机没有专网 公网 1相机自带推流 直接推送到云服务器 然后客户端拉去 2相机只有rtsp ,边缘服务器拉流推送到云服务器 …...