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

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(面向切面编程)作用及其优势 作用:在程序运行期间,在不修改源码的情况下对方法进行功能增强(通知) 优势:减少重复代码,提高代码复用性,提高代码可维护性&#xf…...

[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流模式通信的基本概念和一个简单的示例。 基本概念 面向连接&#xff1…...

从0开始学统计-t分布

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

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&#xff0…...

牛客热题:有效括号

📟作者主页:慢热的陕西人 🌴专栏链接:力扣刷题日记 📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言 文章目录 牛客热题:有效括号题目链接方法一&#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,…...

SwitchyOmega+Burp无感抓包实战:解决HTTPS拦截与流量路由难题

1. 为什么“无感抓包”是BurpSuite日常使用的分水岭刚接触Web安全测试的朋友常有个错觉:装上Burp Suite,配好代理,打开浏览器,点几下网页——流量就该自动进来了。结果现实是:首页打不开、登录态丢失、HTTPS报错满屏、…...

组态王通用扫码枪配置

使用组态王扫码枪驱动,是绑定变量,扫码后直接就可以显示扫码内容。解决每次扫码输入数据时必须先用鼠标点进输入框内的问题。驱动安装先添加驱动,亚控网站的文件为 barcodescanner,这个文件是组态王通用扫码枪的驱动,但…...

Postgresql基础实践教程(八)

⭐️⭐️⭐️⭐️⭐️ 完整数据详见 练习数据免费 ⭐️⭐️⭐️⭐️⭐️ 六十九、查找会员ID 27的向上推荐链 问题 查找会员ID 27的向上推荐链:即推荐该会员的人,以及推荐那个人的人,依此类推。返回会员ID、名字和姓氏。按会员ID降序排列。…...

uWSGI目录穿越漏洞CVE-2018-7490深度利用与防御实战

1. 这不是“读文件”那么简单:uWSGI目录穿越在真实攻防链中的定位与误判代价你刚在Vulfocus靶场里跑通了CVE-2018-7490的PoC,用curl "http://target:8080/?p../../../../etc/passwd"成功读出了root:x:0:0:root:/root:/bin/bash,截…...

在线文档协作工具选型必看:14款产品对比(2026版)

一、在线文档协作工具的概念解析及其核心功能 在线文档协作工具是基于云端的文档创建、编辑、共享与协同沟通平台,核心目标是让团队在同一份资料上“实时共同工作”,减少反复传文件、版本混乱与沟通成本。 企业常见的核心能力包括: 多人实…...

C语言预处理指令全解析

第六章 预处理命令在c语言中,所有# 开头的指令,被称为预处理指令。gcc 编译预处理 所有的预处理指令,都要在这步处理完汇编编译连接#include包含头文件。 全局变量的声明,函数的声明, 自定义构造类型声明, …...

通过Taotoken用量看板清晰追踪各模型的Token消耗情况

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 通过Taotoken用量看板清晰追踪各模型的Token消耗情况 对于依赖大模型API进行开发的个人或团队而言,成本控制与预算规划…...

保姆级教程:Multisim 14.0 从下载到汉化,手把手教你避开安装过程中的那些坑

Multisim 14.0 终极安装指南:从零开始到完美汉化的全流程解析 对于电子工程和自动化领域的学习者与从业者而言,Multisim 14.0 无疑是一款不可或缺的电路设计与仿真工具。然而,许多用户在初次安装过程中常常遇到各种棘手问题,导致软…...

BGP选路原则--本地优先级(LocPrf)

如果BGP收到相同的路由,首选值PrefVal如果也相同的话,那么就会继续比较下一条原则:本地优先级Local_Pref 一、拓扑图 二、配置BGP路由协议: R1 bgp 100 peer 12.1.1.2 as-number 200 peer 13.1.1.3 as-number 200 R2 bgp 200 peer 4.4.4.4 as-number 200 peer 4.4.4…...

保姆级教程:用Cesium ClippingPlaneCollection实现3D地形‘开窗’与‘遮罩’效果

三维地理可视化进阶:Cesium裁剪平面实现区域聚焦与隐藏的艺术 在三维地理信息系统中,有时我们需要突出显示特定区域或隐藏某些部分以查看地下结构——这就像给地球表面开一扇"窗户"或盖一块"遮罩"。Cesium引擎的ClippingPlaneCollec…...