Spring AOP 执行 Pointcut 对应的 Advice 的过程

  • 前言
  • 版本约定
  • 正文
    • jdk proxy 是如何执行 Pointcut 对应的 Advice 的?
      • 获取 Advice 链的过程
    • cglib proxy 是如何执行 Pointcut 对应的 Advice 的?
      • 创建 Enhancer
      • 组装 Callback
      • 拦截 method,执行 Advice 链
  • 小结

前言

实现 Spring AOP 大体会分如下几步:

  1. 找到与 bean 匹配的所有的 Advisor
  2. 使用所有匹配的 Advisor 来为 bean 生成生成动态代理
  3. 通过动态代理类执行 Advice
  4. 将 Spring AOP 与 Spring IoC 进行结合

前面已经分析了第一步 和 第二步,接下来,我们分析一下 第三步:如何通过动态代理类执行 Advice?

版本约定

Spring 5.3.9 (通过 SpringBoot 2.5.3 间接引入的依赖)

正文

Spring 的动态代理类分为两种: jdk proxy 和 cglib proxy。
下面我们就分别来研究一下。

ProxyFactory 是 Spring AOP 用于生成 AOP 代理类的核心类。
AopProxyFactory 是创建 AOP 代理类的工厂接口,它只有一个实现类 DefaultAopProxyFactory,它会根据规则来具体选用 JDK proxy 或者 CGLIB proxy。

jdk proxy 是如何执行 Pointcut 对应的 Advice 的?

JDK proxy 是通过 java.lang.reflect.InvocationHandler#invoke() 来进行方法拦截的。
相应的,我们看下 JdkDynamicAopProxy#invoke() 的源码:

可以看出,JDK proxy 执行 advice 大致分为两步:

  1. 获取与 method 匹配的 Advice 链(AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice)
  2. 使用 ReflectiveMethodInvocation 通过反射来执行 Advice 链 和 joinpoint(目标方法)

获取 Advice 链的过程

// org.springframework.aop.framework.AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice()
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {MethodCacheKey cacheKey = new MethodCacheKey(method);List<Object> cached = this.methodCache.get(cacheKey);if (cached == null) {cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass);this.methodCache.put(cacheKey, cached);}return cached;
}

获取 Advice 链是一个相对耗时的过程,在 proxy 对象 第一次 invoke 执行时,AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice() 会去匹配 method 对应的 Advice 链。

获取 Advice 链的过程,就是将所有的 Advisor 进行遍历,看是否与 Pointcut 匹配,即通过 Pointcut 中的 ClassFilter 和 MethodMatcher 进行匹配过滤,将匹配到的 Advisor 组成一个 Advisor 链(interceptorList)。

第一次获取 Advice 链之后,就会将 Advice 链缓存起来,所以,jdk proxy 类在第一次执行时,是相对比较耗时的

cglib proxy 是如何执行 Pointcut 对应的 Advice 的?

cglib 是通过 Enhancer#create() 来生成代理类的,真正起拦截作用的是 Enhancer 中设置的 Callback 类。

创建 Enhancer

所以,我们首先来看下 Spring AOP 是如何创建 Enhancer 并设置 Callback 的,对应的源码是 CglibAopProxy#getProxy() :

组装 Callback

CglibAopProxy#getCallbacks() 获取 Callback:

可以看出,普通的 Advice 是通过 DynamicAdvisedInterceptor 来拦截执行的。

拦截 method,执行 Advice 链

method 被 DynamicAdvisedInterceptor 拦截的过程:

通过源码,可以看出,cglib proxy 最终拦截 method 之后的处理同 jdk proxy 一样,都是分为两步:

  1. 获取与 method 匹配的 Advice 链(AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice)
  2. 使用 ReflectiveMethodInvocation 通过反射来执行 Advice 链 和 joinpoint(目标方法)

小结

  • JDK proxy
    通过 JdkDynamicAopProxy#getProxy() 来产生代理对象,最终目标方法的拦截是通过 JdkDynamicAopProxy#invoke() 来实现的。
  • CGLIB proxy
    通过 CglibAopProxy#getProxy() 来产生代理对象,最终目标方法的拦截主要是通过 DynamicAdvisedInterceptor#intercept() 来实现的。

不管是 JDK proxy 还是 CGLIB proxy,最终处理目标方法的拦截过程是相同,都会经过两步:

  1. 获取与 method 匹配的 Advice 链(AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice)
  2. 使用 ReflectiveMethodInvocation 通过反射来执行 Advice 链 和 joinpoint(目标方法)

获取与 method 匹配的 Advice 链是一个相对耗时的操作,所以 Spring AOP 将获取到的 Advice 链进行了缓存。


如果本文对你有所帮助,欢迎点赞收藏!

源码测试工程下载:
老王读Spring IoC源码分析&测试代码下载
老王读Spring AOP源码分析&测试代码下载

公众号后台回复:下载IoC 或者 下载AOP 可以免费下载源码测试工程…

文章,请关注公众号: 老王学源码


系列博文:
【老王读Spring AOP-0】SpringAop引入&&AOP概念、术语介绍
【老王读Spring AOP-1】Pointcut如何匹配到 join point
【老王读Spring AOP-2】如何为 Pointcut 匹配的类生成动态代理类
【老王读Spring AOP-3】Spring AOP 执行 Pointcut 对应的 Advice 的过程
【老王读Spring AOP-4】Spring AOP 与Spring IoC 结合的过程 && ProxyFactory 解析
【老王读Spring AOP-5】@Transactional产生AOP代理的原理
【老王读Spring AOP-6】@Async产生AOP代理的原理
【Spring 源码阅读】Spring IoC、AOP 原理小总结

相关阅读:
【Spring源码三千问】Spring动态代理:什么时候使用的 cglib,什么时候使用的是 jdk proxy?
【Spring源码三千问】Advice、Advisor、Advised都是什么接口?
【Spring源码三千问】没有AspectJ,Spring中如何使用SpringAOP、@Transactional?
【Spring源码三千问】Spring AOP 中 AbstractAdvisorAutoProxyCreator、AbstractAdvisingBeanPostProcessor的区别
【Spring 源码三千问】同样是AOP代理bean,为什么@Async标记的bean循环依赖时会报错?

【老王读Spring AOP-3】Spring AOP 执行 Pointcut 对应的 Advice 的过程相关推荐

  1. Spring→面向切面编程AOP、相关概念、通知Advice类型、配置切面切入点通知、AOP相关API、AOP代理类ProxyFactoryBean、AOP注解@AspectJ

    面向切面编程AOP CGLib AOP相关概念 Advice类型 Spring实现AOP Spring配置切面aspect 配置切入点pointcut 配置通知advice 配置通知参数 调用新的父类 ...

  2. 《老王,老刘和老张》《小红和小芳》

    老王,老张和老刘都是美国中西部一个州立大学的博后, 之所以叫做老王,老张,老刘,并不是因为昵称或者爱称, 而是因为他们的确都很老.30多岁还在学校里晃悠,既不是学生,也不是老师, 而且看起来很像老师, ...

  3. Spring的IOC和AOP思想

    Spring框架的两大核心(ioc和aop) 一.ioc:控制反转(Inversion of Control)思想 1.1.由spring来负责控制对象的生命周期和对象间的关系(SSM框架中的依赖关系 ...

  4. 【框架】[Spring]XML配置实现AOP拦截-切点:JdkRegexpMethodPointcut

    转载请注明出处:http://blog.csdn.net/qq_26525215 本文源自[大学之旅_谙忆的博客] 如果你把此种纯Java方式实现AOP拦截读懂了,理解本篇博客会更容易. [框架][S ...

  5. 【Spring】IoC与AOP

    1. Spring 的优点 Spring 是一个开源的.免费的容器(框架) Spring 是一个轻量级的.非侵入式的框架 控制翻转(IOC),面向切面编程(AOP) 支持事务的处理,对框架整合的支持 ...

  6. 【spring 5】AOP:spring中对于AOP的的实现

    在前两篇博客中,介绍了AOP实现的基础:静态代理和动态代理,这篇博客介绍spring中AOP的实现. 一.采用Annotation方式 首先引入jar包:aspectjrt.jar && ...

  7. Spring Aop 常见注解和执行顺序

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:juejin.cn/post/7062506923194581029 Spring 一开始最强大的就是 IOC / AOP 两 ...

  8. Java Spring的IoC和AOP的知识点速记

    Spring简介 Spring解决的最核心的问题就是把对象之间的依赖关系转为用配置文件来管理,这个是通过Spring的依赖注入机制实现的. Spring Bean装配 1. IOC的概念以及在Spri ...

  9. Spring思维导图,让Spring不再难懂(aop篇)

    2019独角兽企业重金招聘Python工程师标准>>> 什么是aop AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Or ...

最新文章

  1. 美国康奈尔大学计算机科学的教授,美国康奈尔大学教授Robbert van Renesse访问并做学术报告...
  2. 2018年6月PMP考试小结-计划和执行收获知识和证书
  3. web异步开发——json
  4. i350t4和v2区别_I350T4V2 英特尔原装I350网卡 全新千兆电口网卡
  5. ext的window如何隐藏水平滚动条
  6. flink sql planner到底是干嘛用的
  7. Windows 10通过本地镜像离线安装.NET 3.5
  8. Nginx负载调度器+双Tomcat负载及会话共享+MySQL后端数据库
  9. 实验报告四 201521430002 张实
  10. RHEL6基础三十七之系统时间修正、GRUB背景图片修改
  11. liunx 监控工具sar
  12. ubuntu 14.04 Dell 台式机 无线网卡驱动安装问题,无线网卡:Qualcomm Atheros Device [168c:0042] (rev 31)
  13. 三种存储类型:块存储、文件存储、对象存储
  14. 浪潮服务器bios怎么找回密码,服务器BIOS密码丢失解决方法
  15. 不在上学了能不能考计算机二级,好多学生都问到底要不要参加计算机二级考试?...
  16. telnet登录SMTP发送邮件
  17. 游戏随机地图生成方法
  18. 只有毅力和决心无往不利
  19. LaTeX编写Elsevier论文格式-小白记录
  20. 第九章 java常用类

热门文章

  1. vs+qt 设置应用程序图标
  2. mvn install BUILD FAILURE : Downloading from central: https://repo.maven.apache.org/maven2/org/sp...
  3. 开源项目之开源的2D游戏引擎 HGE
  4. tsv文件导入mysql
  5. 这个牛逼的在线项目任务管理工具,终于开源了!
  6. QQ群关于C#和php的讨论
  7. layui upload上传携带额外参数
  8. CXPlain: Causal Explanations for Model Interpretation under Uncertainty
  9. 安卓禁用硬件加速_Android硬件加速
  10. 利用keras搭建基础模型莺尾花