Spring Aop 源码解析(下)

ProxyFactory选择cglib或jdk动态代理原理

ProxyFactory在生成代理对象之前需要决定到底是使用JDK动态代理还是CGLIB技术:

config就是ProxyFactory对象,把自己传进来了,因为ProxyFactory继承了很多类,其中一个父类就是ProxyConfig

// config就是ProxyFactory对象// 是不是运行在GraaJVM上面 如果是就用的JDK动态代理
// optimize为true,或proxyTargetClass为true,或用户没有给ProxyFactory对象添加interface
// Optimize默认是false 可以设置为ture,早期版本cglib工作效率高于jdk 后面就差不多了
// isProxyTargetClass()意思是你要代理的是不是类?设置为true 底层就只用cglib 默认false
// 因为jdk只能代理接口,底层就不会关心你传进来的是接口还是类,就算proxyFactory.addInterface()开启接口代理也没用
if (config.isOptimize() || config.isProxyTargetClass() // 判断当前proxyFactory有没有addInterface() 如果添加了 就返回false 调用jdk动态代理// 不会去真正看你的被代理类上是否真的实现了接口 这里之后spring就做了优化|| hasNoUserSuppliedProxyInterfaces(config)) {Class<?> targetClass = config.getTargetClass();if (targetClass == null) {throw new AopConfigException("TargetSource cannot determine target class: " +"Either an interface or a target is required for proxy creation.");}// 如果被代理的类targetClass是接口,直接使用Jdk动态代理if (targetClass.isInterface() // 你设置的类是不是jdk动态代理产生的代理类【非常少用】|| Proxy.isProxyClass(targetClass)) {return new JdkDynamicAopProxy(config);}// 使用Cglibreturn new ObjenesisCglibAopProxy(config);
}
else {// 使用Jdk动态代理return new JdkDynamicAopProxy(config);
}

针对上面第18行

// 如果被代理的类targetClass是接口,直接使用Jdk动态代理

99%不会这么使用 无需掌握 会报错

因为没有设置target,被代理的是哪个对象,它咋增强。。target都是灰色的

总结:

运行在GraaJVM,开启了优化isOptimize,isProxyTargetClass传的代理是不是个类【而不是接口】,hasNoUserSuppliedProxyInterfaces看proxyFactory是不是调用了addInterface()方法,如果以上符合任意一个就会用cglib动态代理,否则用的就是jdk动态代理。

所以在ProxyFactory生成代理对象前会去判断用的哪个动态代理,选定好技术后再调用getProxy()去产生真正的代理对象

JDK动态代理 一行代码搞定【底层就调用newProxyInstance 一模一样 传入类加载器 接口 方法拦截器】

参数:类加载器,添加的接口,传的invokationHandler是this

这里advised其实是proxyFactory,拿到proxyFactory设置的TargetSource,拿到被代理对象然后判断当前执行的啥方法

像equals、hashCode这种方法是不会执行advice的代理逻辑的

如果为true会把代理对象放到ThreadLocal里去

具体可以在proxyFactory设置这个属性,设置为true

只要在当前线程 通过AppContext 可以拿到当前的代理对象了。那这个功能有啥用呢???

可以用于@Transcation失效的场景,自己把它取出来用。例如自己注入自己那个解决事务失效的办法其实也可以用这个方法

取出被代理对象

传入当前正在执行的方法,当前被代理的类到proxyFactory【也就是这里的advised属性】,在getInterceptorsAndDynamicInterceptionAdvice方法里筛选,筛选出符合当前方法和类的advice

我可以添加很多Advisor

先会执行Advice链路,再去执行被代理对象target的方法

如果没有筛选出来,就说明没有代理逻辑要执行,就直接执行被代理的方法

如果有advice就把得到的代理对象,被代理对象,当前执行的方法,参数,被代理的类,以及筛选出来的传进去,然后执行

小总结

由ProxyFactory产生的代理对象底层怎么执行的?

代理对象在执行某个方法的时候,首先取出TargetSource,判断当前执行的方法是什么,如果是equals,hashCode这些就不走代理逻辑,直接执行被代理的方法。如果exposeProxy设置为true会放到TheardLocal里面去,然后调用TargetSource的getTarget方法 取出真正的被代理对象【可以自己实现】,然后筛选匹配的Advice和advisor然后去执行

筛选的详细逻辑

不是每次执行方法都要去找,这里会有个缓存 ,方法作为key

MethodInterceptor非常灵活,底层也用的这个

底层你添加的Advice最后都会转成MethodInterceptor,

config就是ProxyFactory,取出所有的Advisors,那advice去哪了?其实早就把那advice转成Advisor了

理由如下:

===================

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/576620.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

销售的业绩和合同无法统一管理可以通过系统实现吗?

这个问题我们在日常管理中也遇到过&#xff0c;在没有使用软件之前&#xff0c;合同原件没有专人负责打理&#xff0c;销售人员签了合同后&#xff0c;直接把原件随手放在柜子里&#xff0c;或者把数据记录到excel表中。 但是每个人的工作习惯不一样&#xff0c;记录的表格也不…

堆的应用(堆排序,TOP-K问题)详细讲解

所有人都关心我飞的高不高&#xff0c;只有我妈关心我翅膀硬不硬 一、堆的应用 1. 堆排序 1.1 建堆 1.2 利用堆删除思想来进行排序 2.TOP-K问题 二、完结撒❀ –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀–❀–❀–❀–…

第二十一章 Jquery ajax

文章目录 1. jquery下载2. jquery的使用3. jquery页面加载完毕执行4. jquery属性控制6. 遍历器 2. ajax1. 准备后台服务器2. ajax发送get请求3. ajax发送post请求 1. jquery下载 点击下载 稳定版本1.9 2. jquery的使用 存放到html文件的同级目录 3. jquery页面加载完毕执行…

C语言数据结构基础——排序

目录 1.插入排序 2.冒泡排序 3. 堆排序 4.希尔排序 5.直接选择排序 6.快速排序☆☆ 6.1快速排序基础 6.2关于快速排序的时间复杂度 6.3随机数法和三数取中法 6.4其他的单趟实现方法 6.4.1挖坑法 6.4.2前后指针版快速排序☆ 6.4.3非递归实现快排☆ 7.归并排序 7.1递归…

LaTeX 2024下载地址及安装教程

LaTeX是一种流行的排版系统&#xff0c;用于创建高质量的科技和学术文档。相对于传统的字处理软件&#xff0c;如Microsoft Word&#xff0c;LaTeX采用了一种基于标记的方式&#xff0c;通过编写结构化的文本文件&#xff0c;然后使用LaTeX编译器将其转换成漂亮的排版文档。 L…

人才测评系统 提升HR招聘和人岗管理

人才是一个企业的核心竞争力。商业社会的激烈竞争和种种挑战&#xff0c;实际上都是人才的竞争。企业的招聘&#xff0c;职位调动&#xff0c;晋升&#xff0c;人岗匹配的核心对象都是人。现如今&#xff0c;越来越多的企业引入了人才测评机制&#xff0c;但是一些HR却出现不理…

【机器学习】包裹式特征选择之序列后向选择法

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

亚马逊云科技如何看待云计算产业在硬件方面的创新趋势

“真正认真对待软件的人应该制造自己的硬件。” 这是被称为个人电脑之父的艾伦凯博士的一句广为流传的言论。 这种趋势正在云计算行业发生。 目前&#xff0c;全球主流云计算厂商均已加入自研芯片的行列。 如果追溯这一趋势的发展&#xff0c;亚马逊云技术无疑是领先者。 在r…

数据结构与算法分析2栈、队列

1.栈和队列本质上都是表&#xff0c;所以他们都有两种实现方式&#xff0c;链表实现和数列实现。栈的特点是后进先出。 2.栈的实现 3.应用有&#xff1a; 4.栈的危险操作&#xff1a;用尽栈空间&#xff0c;导致内容占用到别的寄存器里面去了&#xff0c;从而出现异常。还有尾…

「JavaSE」Lambda表达式

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;快来卷Java啦 &#x1f387;欢迎点赞收藏加关注哦&#xff01; Lambda表达式 &#x1f349;简介&#x1f349;函数式接口&#x1f34c;注解 &#x1f349;语法&#x1f349;Lambda表达式的基本…

每天学习一点点之注解处理器 APT

APT&#xff08;Annotation Processing Tool&#xff09;是一种处理注解的工具&#xff0c;它能够对源代码文件进行检测并找出其中的注解&#xff0c;然后对其进行额外的处理。由于注解处理过程是在编译时完成的&#xff0c;并不会影响程序的运行时性能。 APT 能做什么&#x…

js的Date对象

文章目录 1. 概念2. 创建时间对象2.1. 方式一2.2. 方式二2.3. 方式三2.4. 使用场景 3. 获取年月日4. 获取时分秒5. 获取毫秒值6. 封装获取当前时间函数 1. 概念 Date 对象用于处理日期与时间。 2. 创建时间对象 2.1. 方式一 使用无参构造&#xff0c;创建出来的就是当前的时…