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.rhkb.cn/news/290842.html

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

相关文章

02正式学习第一天

1、windows上加载socket库 链接输入ws2_32.lib 代码code&#xff1a; #ifdef _WIN32 #include<windows.h> #else #include <sys/socket.h> #include<sys/types.h> #include<unistd.h> #include<cstring> #include<arpa/inet.h> #include…

【Java】LinkedList模拟实现

目录 整体框架IMyLinkedList接口IndexNotLegalException异常类MyLinkedList类成员变量(节点信息)addFirst(头插)addLast(尾插)在指定位置插入数据判断是否存在移除第一个相等的节点移除所有相等的节点链表的长度打印链表释放回收链表 整体框架 IMyLinkedList接口 这个接口用来…

WPF 路由事件 数据驱动 、Window 事件驱动

消息层层传递&#xff0c;遇到安装有事件侦听器的对象&#xff0c;通过事件处理器响应事件&#xff0c;并决定事件是否继续传递&#xff1b; 后置代码中使用AddHandler方法设置事件监听器&#xff0c;该方法的 第一个参数是指定监听的路由事件类型对象&#xff0c; 第二个参数…

微服务demo(四)nacosfeigngateway

一、gateway使用&#xff1a; 1、集成方法 1.1、pom依赖&#xff1a; 建议&#xff1a;gateway模块的pom不要去继承父工程的pom&#xff0c;父工程的pom依赖太多&#xff0c;极大可能会导致运行报错&#xff0c;新建gateway子工程后&#xff0c;pom父类就采用默认的spring-b…

CSS之动画

一&#xff0c;动画的制作 实现盒子绕圈走 二&#xff0c; 动画的常用属性 三&#xff0c;动画简写属性 前面两个属性一定要写&#xff0c;第三个linear是指匀速的意思&#xff08;默认是ease&#xff09;

【快速解决】解决谷歌自动更新的问题,禁止谷歌自动更新,如何防止chrome自动升级 chrome浏览器禁止自动升级设置方法

目录 问题描述 解决方法 1、搜索栏搜索控制面板 2、搜索&#xff1a;服务 ​编辑 3、点击Windows工具 4、点击服务 ​5、禁止谷歌更新 问题描述 由于我现在需要装一个谷歌的驱动系统&#xff0c;但是目前的谷歌驱动系统的版本都太旧了&#xff0c;谷歌自身的版本又太新了…

手写简易操作系统(十五)--实现内核线程

前情提要 前面我们实现了内存管理系统&#xff0c;内存管理系统可以实现进程与进程之间的隔离。 Linux中高1GB是操作系统内核的地址&#xff0c;低3GB是用户的地址&#xff0c;高1GB对于所有用户都是一致的&#xff0c;低3GB才是用户自己的自留地。 既然已经实现了内存管理&…

[flink 实时流基础] flink组件栈以及任务执行与资源划分

文章目录 7. Flink组件栈1. 部署层&#xff08;1&#xff09;Local模式&#xff08;2&#xff09;Cluster模式&#xff08;3&#xff09;Cloud模式 2.运行时3.API层4. 上层工具 8. 任务执行与资源划分1. 再谈逻辑视图到物理执行图2. 任务、算子子任务与算子链3. Slot与计算资源…

Linux文件IO(2):使用标准IO进行文件的打开、关闭、读写、流定位等相关操作

目录 前言 文件的打开和关闭的概念 文件的打开 文件的打开函数 文件打开的模式 文件的关闭 文件的关闭函数 注意事项 字符的输入&#xff08;读单个字符&#xff09; 字符输入的函数 注意事项 字符的输出&#xff08;写单个字符&#xff09; 字符输出的函数 注意…

Git版本管理使用手册 - 8 - 合并分支、解决冲突

合并整个开发分支 切换到本地test分支&#xff0c;选择右下角远程开发分支&#xff0c;选择Merge into Current。然后提交到远程test仓库。 合并某次提交的代码 当前工作区切换成test分支&#xff0c;选择远程仓库中的dev开发分支&#xff0c;选择需要合并的提交版本右击&a…

HarmonyOS实战开发-实现Ability内页面间的跳转和数据传递。

介绍 本篇Codelab基于Stage模型下的Ability开发&#xff0c;实现Ability内页面间的跳转和数据传递。 最终效果图如下&#xff1a; 相关概念 页面路由&#xff1a;提供通过不同的url访问不同的页面&#xff0c;包括跳转到应用内的指定页面、用应用内的某个页面替换当前页面、…

网络七层模型之物理层:理解网络通信的架构(一)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

企业数据资产管理的战略价值与实施策略

一、引言 数据资产不仅记录了企业的历史运营情况&#xff0c;更能够揭示市场的未来趋势&#xff0c;为企业的决策提供有力支持。因此&#xff0c;如何有效地管理和利用数据资产&#xff0c;已经成为企业竞争力的重要体现。本文将探讨企业数据资产管理的战略价值与实施策略&…

【Java多线程】3——Lock API控制多线程

3 Lock API控制多线程 ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记仓库&#x1f449;https://github.com/A-BigTree/tree-learning-notes 个人主页&#x1f449;https://www.abigtree.top ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个…

【JavaScript算法】DOM树层级显示

题目描述&#xff1a; 上述表达式的输出结果为 [DIV] [P, SPAN, P, SPAN] [SPAN, SPAN]直接上代码 let tree document.querySelector(".a"); function traverseElRoot(elRoot) {const result [];function traverse(element, level) {if (!result[level]) {resul…

ASR-LLM-TTS 大模型对话实现案例;语音识别、大模型对话、声音生成

参考:https://blog.csdn.net/weixin_42357472/article/details/136305123(llm+tts) https://blog.csdn.net/weixin_42357472/article/details/136411769 (asr+vad) 这里LLM用的是chatglm;电脑声音播报用的playsound 1、实时语音识别版本 注意:暂时这项目有个缺陷就是tts…

HarmonyOS 应用开发之UIAbility组件启动模式

UIAbility的启动模式是指UIAbility实例在启动时的不同呈现状态。针对不同的业务场景&#xff0c;系统提供了三种启动模式&#xff1a; singleton&#xff08;单实例模式&#xff09;multiton&#xff08;多实例模式&#xff09;specified&#xff08;指定实例模式&#xff09;…

成都市酷客焕学新媒体科技有限公司:实现品牌的更大价值!

成都市酷客焕学新媒体科技有限公司专注于短视频营销&#xff0c;深知短视频在社交媒体中的巨大影响力。该公司巧妙地将品牌信息融入富有创意和趣味性的内容中&#xff0c;使观众在轻松愉悦的氛围中接受并传播这些信息。凭借独特的创意和精准的营销策略&#xff0c;成都市酷客焕…

5、axios请求、动画、组件、路由重定向、UI组件

一、axios请求 Axios是一个基于Promise的HTTP状态库&#xff0c;封装ajax。ajax包含axios安装 npm install axios 引入 import axios form “axios” 1、get请求 <script> // 1.本页面引入 import axios from "axios";data() {return {imgSrc: ""…

pygame用chatgpt绘制3d沿x轴旋转的

import pygame from pygame.locals import * import sys import mathpygame.init()width, height 800, 600 screen pygame.display.set_mode((width, height))vertices [(0, 100, 0), (100, 200, 0), (300, 100, 0)]angle 0 rotation_speed 2 # 可根据需要调整旋转速度 c…