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

动态代理大总结

1.开启EnableAspectJAutoProxy注解

@EnableAspectJAutoProxy注解【相当于加了个BeanPostProcessor】,会导入AspectJAutoProxyReqistrar这个类,会把AnnotationAwareAspectJAutoProxyCreator注册进spring容器中,注册进容器后还会看这两个属性的值【proxyTargetClass,exposeProxy】基于BeanDefinition技术给这两个属性赋值,也就是实例化创建完对象后有个BeanDefinition后置处理【getPropertiseValue().add() 。proxyTargetClass属性决定了Spring AOP使用JDK动态代理还是CGLIB来创建代理对象。true就是用CGLIB exposeProxy为true就是能从【AopCOntext.currentProxy( )】ThreadLocal里拿到代理对象】

当执行到初始化后的方法时候,会遍历所有的BeanPostProcessor,然后就执行到AnnotationAwareAspectJAutoProxyCreator他父类的这个方法,然后会基于bean去创建代理对象【这里是UserService为例】。

2.基于bean创建代理对象

1.首先会判断是不是AOP的基础设施类,如果bean是这些类型就无需Aop【包括Aspect切面bean Advisor类 Advice类等等】,然后把bean名字放入map,value为false无需Aop做个缓存,这里也可以自定义扩展哪些bean不用进行Aop,无需Aop直接返回普通对象。

如何找的Advisor?

先去找所有的Advisor【通过bean工厂找到所有显式定义的Advisor类型的bean 支持Order注解排序 放入list】然后还会找到@Aspect切面【遍历所有bean 看哪个类上有@Aspect注解 】里的所有没有加@PointCut注解的方法,然后按照通知的指定顺序和方法名字进行排序,接下来把方法就封装成Advisor,最后加入list,这时list就是最完整的了。然后对总的list进行筛选【类匹配器,方法匹配器(这里面应该有3次匹配)】和排序,最后返回的就是符合条件的所有Advisor。

切面方法的Advisor是怎么生成的?

会先拿到注解上写的PointCut,如果没有写那这个方法就被过滤掉了,还有另一种写法不会被过滤。

然后过滤完返回的就是Advisor对象了。

如果最后有匹配上的ProxyFactory就会去创建代理对象了

3.ProxyFactory创建代理对象

JDK或者CGLIB调用对应的方法

前情提要:

ProxyFactory在生成代理对象之前,也就是最后一步才需要决定到底是使用JDK动态代理还是CGLIB技术【最后调用createProxy().getProxy()方法的时候 】去生成代理对象

4.得到代理对象后调用代理对象的方法

JDK

JDK产生的代理对象最后再执行某个方法的时候都会进到invoke方法里来

invoke方法详解

代理对象在执行某个方法的时候:

1.首先取出TargetSource,然后判断当前执行的方法是什么,如果是equals,hashCode这些就不走代理逻辑,就直接执行被代理的方法。如果exposeProxy设置为true会把代理对象放到TheardLocal里面去,然后调用TargetSource的getTarget方法 取出真正的被代理对象【这部分也可以自己实现】

2.然后筛选匹配的Advisor然后去执行【遍历所有的Advisor 然后通过Pointcut筛选 类匹配器

http://www.lryc.cn/news/326374.html

相关文章:

  • 理解Harris角点检测的数学原理
  • ETIM -国际贸易的产品分类标准
  • MySQL高阶SQL语句
  • 聊聊CSS
  • C语言 青蛙跳台阶问题
  • 【Django开发】前后端分离美多商城项目第3篇:用户部分,1. 后端接口设计:【附代码文档】
  • DHCP snooping、DHCP安全及威胁防范
  • 用eclipse创建Web项目,通过Servlet实现Web访问的功能。
  • tools.jar下载 Unable to create schema compiler
  • 【0278】checkpointer 共享内存(CheckpointerShmem)初始化(3)
  • 算法打卡day29|贪心算法篇03|Leetcode 1005.K次取反后最大化的数组和、134. 加油站、135. 分发糖果
  • 【hexo博客6】自定义域名 购买、配置、更新部署
  • Django使用pyJwt进行token校验
  • ❤️算法笔记❤️-(每日一刷-26、删除有序数组的重复项)
  • 银河麒麟系统安装设备类型选择lvm简单模式之后,数据写入导致失败导致系统重启无法正常加载
  • Mybatis-核心配置文件 / Mybatis增删改查
  • Nginx(面试)
  • net::ERR_SSL_PROTOCOL_ERROR
  • BaseDao封装增删改查(超详解)
  • 【Python操作基础】——元组
  • 光伏投融资该如何计算?
  • 【更新中】Leetcode中遇到的最短路径算法
  • Git学习笔记之基础
  • STCubeIDE 编译bootloader
  • Python学习:函数
  • docker run 使用 -p 命令一直显示端口被占用
  • Rust 实战练习 - 1. 输入,输出,环境变量,字符,字符串
  • RuoYi-Vue-Plus(登录流程)
  • 【数学】 【分数】 【字符串】972. 相等的有理数
  • 【4】DongshanPI-Seven 应用开发_文件IO