spring的aop底层实现原理

spring的aop底层实现原理今日分享开始啦,请大家多多指教~spring aop使得我们的aop开发工作变得简单,这是众所周知的。今天我们一起揭秘spring aop底层原理及实现吧!AOP面向切面编程:主要是通过切面类来提高代码的复用,降低业务代码的耦合性,从而提高开发效率。主要的功能是:日志记录

今日分享开始啦,请大家多多指教~

spring aop使得我们的aop开发工作变得简单,这是众所周知的。今天我们一起揭秘spring aop底层原理及实现吧!

spring的aop底层实现原理

AOP面向切面编程:主要是通过切面类来提高代码的复用,降低业务代码的耦合性,从而提高开发效率。主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。

  • AOP实现原理:aop是通过cglib的动态代理实现的。
  • jdk动态代理:利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
  • cglib动态代理:将代理对象类的class文件加载进来,通过ASM字节码技术修改其字节码生成子类来处理。

区别:JDK动态代理只能对实现了接口的类生成代理,而不能针对类 。CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 。因为是继承,所以该类或方法最好不要声明成final ,final可以阻止继承和多态。

使用

要分析spring aop的底层原理,首先要会使用,先创建一个普通maven webapp项目,引入spring-context依赖,版本为5.1.1RELEASE。

spring的aop底层实现原理

然后我使用aspectj作为aop的语法实现,和spring整合起来。

spring的aop底层实现原理

接下来我全称用注解的形式来模拟spring aop的使用,先创建一个配置类去扫描包,开启aspectJ的自动代理支持。

spring的aop底层实现原理

然后新建一个接口和接口的实现类:

spring的aop底层实现原理

创建切面:

spring的aop底层实现原理

创建测试方法:

spring的aop底层实现原理

执行方法,可以看到在打印query…之前打印了before———-

这个时候我们很想知道为什么这句before会打印在query之前呢,稍微对spring aop有所了解的人应该知道,spring是通过动态代理和字节码技术来实现aop操作的,也就是经常说的jdk动态代理和cglib动态代理两种模式,那么,spring究竟是怎么创建的代理对象,又是什么时候产生的代理对象呢,下面我们来一起探究一下源码,来揭开这个谜底。

源码分析

首先我们透过现象看本质,我先把断点打在测试方法的最后一行,我们来看这个时候的dao对象。

那么接下来我们就要去找到什么时候这个dao对象变成了动态代理对象的,既然在最后一行的时候对象已经变成了代理对象,那么我门自然就猜想是在上一句代码的位置spring执行了创建代理对象的操作,我们把断点移到上一行,debug进去。

spring的aop底层实现原理

这行代码我看方法名觉得应该是有用的代码,方法意思应该是spring处理好的bean,跟进去看看。

spring的aop底层实现原理

spring的aop底层实现原理

spring的aop底层实现原理

执行完getBeanNamesForType(requiredType)后,我们看idea的变量显示,果然有一个bean,name是IndexDao。

spring的aop底层实现原理

那么接下来自然会进到length==1的那个代码块,这时候我再debug进入,这里还是一个getBean方法。

spring的aop底层实现原理

spring的aop底层实现原理

在spring容器中还有一些没有name的其他的bean需要被创建,所以这里我用上了条件断点,当beanName等于indexDao的时候,才会进入断点,但是当我F8跑完这行代码的时候,出乎意料的事情发生了。

spring的aop底层实现原理

惊不惊喜,意不意外,getSingleton这行代码执行结束之后,代理对象就已经被创建了,所以需要debug进入这行代码去看。

spring的aop底层实现原理

但是我在这里只看到了get方法,那么这些bean是什么时候放到singletonObjects里的呢,我来找找。

spring的aop底层实现原理


DefaultSingletonBeanRegistry注册器中,我找到了singletonObjects.put方法,代表bean是这个时候被放到这个map里去的,接下来我在这行代码上进行条件断点,然后我们来看它的调用链,找出是什么时候执行的addSingleton方法,其实从这个时候我已经知道,断点打在测试方法的倒数第二行是不对的,在getBean之前其实代理对象已经产生了。

spring的aop底层实现原理

spring的aop底层实现原理

在createBean方法上,我也加上条件断点,然后debug进入。

spring的aop底层实现原理

spring的aop底层实现原理

接下来我debug进入doCreateBean方法

spring的aop底层实现原理

spring的aop底层实现原理

spring的aop底层实现原理

spring的aop底层实现原理

spring的aop底层实现原理

debug跟进initializeBean方法,条件断点在两个初始化处理器上,我隐约觉得代理对象就是从这两个方法中产生的,我们拭目以待。

spring的aop底层实现原理

执行完
applyBeanPostProcessorsBeforeInitialization方法,这个时候我们看到warppedBean还是indexDao,并没有产生代理对象。

spring的aop底层实现原理

我猜想在下一个后置处理器中,代理对象将被创建,我debug进去。

spring的aop底层实现原理

spring的aop底层实现原理

看到这个处理器,我豁然开朗,应该就是经过这个处理器的处理产生的代理对象了,跑完这段代码来验证一下我的猜想。

spring的aop底层实现原理

可以看到我的猜想被证明是正确的,运行完这个后置处理器,代理对象就被创建出来了。 到了这里我们知道了代理对象是从哪里来的了,但是还是没搞清楚代理对象是怎么创建出来的,这时候我们就需要debug进入到这个处理器内部去瞧瞧了。

spring的aop底层实现原理

于是乎我又进到了wrapIfNecessary这个方法内部

spring的aop底层实现原理

spring的aop底层实现原理

spring的aop底层实现原理

我们看到这里有一个if语句,当config中的isOptimize和isProxyTargetClass还有
hasNoUserSuppliedProxyInterfaces三个判断条件只要有一个满足的话,spring就会选择cglib的方式进行动态代理,而config中的两个boolean变量的默认值都是false,而我们的被代理对象又是实现接口的,所以spring会选择jdk动态代理的实现形式来完成动态代理。

当然,我们也可以在这种情况下手动的配置config值来让spring选择cglib作为动态代理的实现方式,稍后会演示。

spring的aop底层实现原理

spring的aop底层实现原理

来演示一下怎么修改config让spring在有接口的情况下选择cglib作为动态代理的实现方式,其实很简单,在配置类的这个注解后加上proxyTargetClass=true就可以了。

@EnableAspectJAutoProxy(proxyTargetClass = true)

spring的aop底层实现原理

总结

我以spring aop实现的调用链图来结束这次的总结

spring的aop底层实现原理

今日份分享已结束,请大家多多包涵和指点!

激活谷谷主为您准备了激活教程,为节约您的时间请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/15381.html

(0)
上一篇 2024年 5月 18日
下一篇 2024年 5月 18日

相关推荐

  • ubuntu和linux什么关系_ubuntu和linux安装哪一个更好

    ubuntu和linux什么关系_ubuntu和linux安装哪一个更好EMBY入门全攻略:打造个人影视媒体库前言可能你有些疑惑,什么是EMBY?为什么我需要它?简单来说,Emby是一款非常出色的媒体服务器软件。如果你是个影视爱好者,想要一个能够让你的数字媒体集中管理,智能分类,远程访问,并且具有出色用户体验的平台,

    激活谷笔记 2024年 5月 13日
  • 积分电路的工作原理及电路图_积分电路的工作原理及电路图讲解

    积分电路的工作原理及电路图_积分电路的工作原理及电路图讲解差分放大电路原理一、差分放大电路这里主要介绍两种不同类型的差分放大器电路:1、BJT差分放大电路设计2、运算放大器设计差分电路二、BJT差分放大电路1、差分放大电路图如下面的电路图所示,有两个输入 Iput1 和 Iput 2 以及两个输出 V1out 和 V2o

    2024年 5月 29日
  • WebStorm激活2024.1.1(Webstorm 2024.1.1 最新激活码,激活成功教程版安装教程(亲测有效~))

    WebStorm激活2024.1.1(Webstorm 2024.1.1 最新激活码,激活成功教程版安装教程(亲测有效~))

    2024年 6月 7日
  • cpu测试性能_cpu性能测试工具有哪些

    cpu测试性能_cpu性能测试工具有哪些主流与高端的同台较量,英特尔第13代酷睿i5-13490F&i7-13700KF评测分析英特尔从Alder Lake到Raptor Lake的更新基本上就突出一个稳扎稳打,一方面是从12代的全新异构体系+率先引入PCIe 5.0和DDR5新特性之后已经属于一次大改;另一方面英特尔自

    2024年 5月 24日
  • c语言中的内存指什么_c语言中的内存指什么意思

    c语言中的内存指什么_c语言中的内存指什么意思C语言学习之内存理解文章目录 一、程序运行为什么要内存1.1 计算机的运行目的1.2冯洛伊曼结构和哈弗结构1.3动态内存DRAM,静态内存SRAM1.4为啥需要内存 二、位、字节、半字、字的概念和内存位宽2.1什么是内存2.2内存的大小2.3内

    2024年 5月 25日
  • snipaste能截长图吗_怎么用snipaste截长图

    snipaste能截长图吗_怎么用snipaste截长图snipaste怎么截长图?安利都写snipaste可以截长图,但是到底怎么截啊?搜了一下午才发现截不了,推荐用FastStone Capture或sigusoft截图截文档或者代码全图的话,可以选中要截取的部分,比如截全部就Ctrl+A,然后Ctrl+C进行复制,然后按F3键就可以了,前提是

    激活谷笔记 2024年 5月 13日
  • ddy是啥意思_huddy是啥意思

    ddy是啥意思_huddy是啥意思蜜蜂欢乐社、心愿社08月18日直播预告图文版清单剧透​​👇👇👇👇👇👇👇👇👇👇👇👇【¥19.9】FAB面霜28.3g*5口令:0$7p8vdDbbvkL$:// MF3135👆👆👆👆👆👆ONCHA大红袍福建武夷山乌龙茶

    激活谷笔记 2024年 5月 25日
  • linux 查询cpu温度_linux查询cpu温度命令

    linux 查询cpu温度_linux查询cpu温度命令linux查看cpu温度命令在Linux系统中,可以使用一些命令来查看CPU的温度。下面介绍几种常用的方法。1. 使用sensors命令:sensors是一个用于查看各种传感器信息的工具。当安装了相应的传

    激活谷笔记 2024年 5月 24日
  • 多线程同步的几种方法_多线程同步的几种方法有哪些

    多线程同步的几种方法_多线程同步的几种方法有哪些线程同步的几种方式前言进程有自己的独立地址空间,因此进程之间重点通信,通信方式包括:管道Pipe、命名管道FIFO、消息队列MessageQueue、共享存储SharedMemory、信号量Semaphore、套接字Socket和信号Signal

    2024年 5月 20日
  • vue form表单提交增加

    vue form表单提交增加这是一个注册需求,要求用户在注册的时候需要填写注册信息并上传“营业执照”等信息。表单内容需进行验证及必填项提示,图片需要和信息一起传递且图片载入后需可预览。既然是注册我们当然是用form表单来提交了,对应的El

    激活谷笔记 2024年 5月 19日
  • reportviewer控件详解

    reportviewer控件详解当使用Crystal Reports进行报表开发时,你可以按照以下步骤进行:1. 安装Crystal Reports:首先,你需要安装Crystal Reports Designer并将其集成到Visual Studio中。你可以从SA

    激活谷笔记 2024年 5月 19日
  • bios中设置uefi启动_bios设置uefi启动的步骤

    bios中设置uefi启动_bios设置uefi启动的步骤已经装好了系统,要怎么才能把启动方式改成UEFI启动?一些电脑用户会遇到这样的问题:已经装好了系统,不想重装,不想格式化分区,怎么才能把系统从传统BIOS启动改成UEFI启动?本文将图文并茂地一步一步教你怎么改,小白也能做。此操作适合Win8以上系统,Wi

    2024年 5月 22日
关注微信