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

OpenAPI SDK组件之Spring Aop源码拓展

Spring Aop

看这个分享的应该都用过Spring Aop,这里就不再过多介绍了它是什么了。

我抽取了Spring Aop的部分源码,通过它实现请求参数可变拦截,同时apisdk离开Spring框架,仍然可以正常运行。

讲拦截也好,通知也罢,大家知道是什么意思就行了,不需要纠结这个叫法。

核心拓展类

利用Aop的前置通知,拓展了前置参数可变通知,原理是在运行的过程中,动态封装请求上下文SdkContext参数,变更请求参数。

在这里插入图片描述

上面圈的类是参照Aop的代码结构,拓展出的通知,描述如下:

  • MethodBeforeArgsChangeableAdvice:需要开发者实现的接口,在apisdk中唯一实现SdkContextArgsBeforeChangeableAdvice,实现了SdkContext的构建
  • MethodBeforeChangeableAdviceAdapter:适配器,把开发者实现的MethodBeforeArgsChangeableAdvice交给底层去执行,是框架执行开发者代码的入口
  • MethodBeforeChangeableAdviceInterceptor:执行开发者的MethodBeforeArgsChangeableAdvice,最后把结果添加到方法参数上
  • SdkContextArgsBeforeChangeableAdvice:MethodBeforeArgsChangeableAdvice的唯一实现,实现了SdkContext的关键代码

核心代码

SdkContext自动封装

public class SdkContextArgsBeforeChangeableAdvice implements MethodBeforeArgsChangeableAdvice {@Overridepublic Object before(Method method, Object[] args, Object target) throws Throwable {// 判断执行的方法是否需要自动注入 SdkContext// 如果用户的接口声明的方法参数有 SdkContext,则说明用户要手动创建,否则底层自动创建boolean isAutoType = MethodWrapperCache.isAutoType(method);if (isAutoType) {// SdkContextManager 封装了域名、secret、token等服务的调用SdkContextManager instance = SdkContextManager.getInstance();SdkContext sdkContext = instance.getSdkContext();return sdkContext;}return null;}
}

动态调整请求参数

MethodBeforeChangeableAdviceInterceptor

public class MethodBeforeChangeableAdviceInterceptor implements MethodInterceptor, BeforeAdvice {private MethodBeforeArgsChangeableAdvice advice;public MethodBeforeChangeableAdviceInterceptor(MethodBeforeArgsChangeableAdvice advice) {this.advice = advice;}@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {// 调用开发者的 MethodBeforeArgsChangeableAdviceObject arg = this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());if (arg != null && mi instanceof ReflectiveMethodInvocation) {// 将 MethodBeforeArgsChangeableAdvice 返回的结果,添加到调用方法((ReflectiveMethodInvocation) mi).appendArgument(arg);}return mi.proceed();}
}

ReflectiveMethodInvocation#appendArgument

public class ReflectiveMethodInvocation implements MethodInvocation {// 方法参数protected Object[] arguments;// 调整方法请求参数public void appendArgument(Object obj) {if (this.arguments != null && this.arguments.length > 0) {int length = this.arguments.length;Object[] newArgs = new Object[length + 1];System.arraycopy(this.arguments, 0, newArgs, 0, length);newArgs[length] = obj;this.arguments = newArgs;} else {this.arguments = new Object[1];this.arguments[0] = obj;}}
}

Jdk 动态代理

原始接口A和增强接口B,他们的实例化必须由动态代理支持。apisdk有SdkManager和JdkDynamicAopProxy两个代理对象生成器,SdkManager是原代码中就有的,JdkDynamicAopProxy是我参考Spring aop拓展的。

二开后,SdkManager用于生成B的代理对象,JdkDynamicAopProxy用于生成A的代理对象,并且配置了一系列的拦截动作。

开发逻辑:开发者使用A的代理对象,调用方法,底层执行A方法,执行拦截动作,再拿到B的代理对象,执行B的方法。

JdkDynamicAopProxy代码如下:

public class JdkDynamicAopProxy implements InvocationHandler {// 包装被代理的对象,每个被代理的对象都有一组Adviceprivate AdvisedSupport advised;public JdkDynamicAopProxy(AdvisedSupport advised) {this.advised = advised;}public Object getProxy() {return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), advised.getProxiedInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 获取被代理的对象Object target = advised.getTarget();// 获取 Method 匹配的所有 AdviceList<Object> chain = this.advised.getInterceptors(method, target.getClass());Object retVal;if (chain.isEmpty()) {// 没有 Advice,直接执行 MethodretVal = method.invoke(target, args);} else {// 递归调用 AdviceReflectiveMethodInvocation reflectiveMethodInvocation = new ReflectiveMethodInvocation(proxy, target, method, args, chain);retVal = reflectiveMethodInvocation.proceed();}return retVal;}
}

相关文章:

OpenAPI SDK组件之Spring Aop源码拓展

Spring Aop 看这个分享的应该都用过Spring Aop&#xff0c;这里就不再过多介绍了它是什么了。 我抽取了Spring Aop的部分源码&#xff0c;通过它实现请求参数可变拦截&#xff0c;同时apisdk离开Spring框架&#xff0c;仍然可以正常运行。 讲拦截也好&#xff0c;通知也罢&a…...

蓝桥杯C/C++VIP试题每日一练之龟兔赛跑预测

&#x1f49b;作者主页&#xff1a;静Yu &#x1f9e1;简介&#xff1a;CSDN全栈优质创作者、华为云享专家、阿里云社区博客专家&#xff0c;前端知识交流社区创建者 &#x1f49b;社区地址&#xff1a;前端知识交流社区 &#x1f9e1;博主的个人博客&#xff1a;静Yu的个人博客…...

为你的Vue2.x老项目安装Vite发动机吧

天下苦webpack久矣&#xff0c;相信作为前端开发者一定经历过在项目迭代时间较长的时候经历漫长等待的这一过程&#xff0c;每一次保存都会浪费掉大量时间&#xff0c;这是webpack这种机制所带来的问题。 于是&#xff0c;尤大为我们带来了新一代前端构建工具&#xff1a;vite…...

ZCMU--5012: 铺设道路(差分思路)

Description 春春是一名道路工程师&#xff0c;负责铺设一条长度为 n 的道路。 铺设道路的主要工作是填平下陷的地表。 整段道路可以看作是 n 块首尾相连的区域&#xff0c;一开始&#xff0c;第 i 块区域下陷的深度为 di。  春春每天可以选择一段连续区间 [L,R]&…...

算法模板总结(自用)

算法模板总结滑动窗口双指针算法数组相关合并两个有序数组左右指针技巧快慢指针技巧字符串相关左右指针反转字符串问题快慢指针替换空格字符问题链表相关快慢双指针删除链表的倒数第N个节点链表相交环形链表链表操作几数之和两数之和四个数组的四数之和三数之和同一数组中四数之…...

【架构师】零基础到精通——架构发展

博客昵称&#xff1a;架构师Cool 最喜欢的座右铭&#xff1a;一以贯之的努力&#xff0c;不得懈怠的人生。 作者简介&#xff1a;一名Coder&#xff0c;软件设计师/鸿蒙高级工程师认证&#xff0c;在备战高级架构师/系统分析师&#xff0c;欢迎关注小弟&#xff01; 博主小留言…...

C++(20):三路比较运算符

C20增加了三路比较运算符<>&#xff08;戏称航天飞机运算符&#xff09;&#xff0c;用于对类的比较运算符进行统一的设计。有两种使用方式&#xff1a;默认比较对于某些类&#xff0c;如果按照其成员逐一比较即可决定比较运算符的值&#xff0c;那么可以使用默认的三路运…...

MySQL workbench 字符集、字符序的概念与联系

在数据的存储上&#xff0c;MySQL提供了不同的字符集支持。而在数据的对比操作上&#xff0c;则提供了不同的字符序支持。 MySQL提供了不同级别的设置&#xff0c;包括server级、database级、table级、column级&#xff0c;可以提供非常精准的设置。 什么是字符集、字符序&am…...

DBA之路---数据库启动与关闭过程

DBA之路—数据库启动与关闭过程 1、启动过程 oracle启动的四个状态 shutdown、就是数据库关闭状态。 nomount模式 #启动instance &#xff0c;读取参数文件、分配sga空间启动后台进程&#xff0c;打开alter日志和其他trace文件startup nomount #该模式下只会创建实例并不加…...

Shell文件包含

和其他语言一样&#xff0c;Shell 也可以包含外部脚本。这样可以很方便的封装一些公用的代码作为一个独立的文件。 一、语法格式 Shell 文件包含的语法格式如下&#xff1a; . filename # 注意点号(.)和文件名中间有一空格 或 source filename 在当前bash环境下读取并执行file…...

计算机网络(六): HTTP,HTTPS,DNS,网页解析全过程

文章目录一、HTTP头部包含的信息通用头部请求头部响应头部实体头部二、Keep-Alive和非Keep-Alive的区别三、HTTP的方法四、HTTP和HTTPS建立连接的过程4.1 HTTP4.2 HTTPS五、HTTP和HTTPS的区别六、HTTPS的加密方式七、cookie和sessionsessioncookie八、HTTP状态码状态码200&…...

Android仿京东金融的数值滚动尺功能

自定义数值滚动尺,这个用的还是挺多的&#xff0c;例如京东金融的通过滚动尺选择金额等,而这次就是高仿京东金融的数值滚动尺。首先看看下效果图&#xff0c;如下&#xff1a;首先先给你们各个变量的含义&#xff0c;以免在后面的讲解中不知变量的意思&#xff0c;代码如下://最…...

Nginx 和 Tomcat 实现负载均衡

Nginx 和 tomcat 实现负载均衡 &#x1f3c6;荣誉认证&#xff1a;51CTO博客专家博主、TOP红人、明日之星&#xff1b;阿里云开发者社区专家博主、技术博主、星级博主。 &#x1f4bb;微信公众号&#xff1a;微笑的段嘉许 &#x1f4cc;本文由微笑的段嘉许原创&#xff01; &am…...

【万能排序之qsort、b_sort 、s_sort】

文章目录前言:star:qsort函数函数参数qsort函数的使用:star:模拟实现万冒泡排序函数参数模拟实现b_sort注意点:star:模拟实现万能选择排序函数参数模拟实现s_sort最后前言 我们所熟悉的冒泡排序&#xff0c;选择排序&#xff0c;插入排序&#xff0c;二分排序等都是基于给定的一…...

利用InceptionV3实现图像分类

最近在做一个机审的项目&#xff0c;初步希望实现图像的四分类&#xff0c;即&#xff1a;正常&#xff08;neutral&#xff09;、涉政&#xff08;political&#xff09;、涉黄&#xff08;porn&#xff09;、涉恐&#xff08;terrorism&#xff09;。有朋友给推荐了个github上…...

【Java】CAS锁

一、什么是CAS机制&#xff08;compare and swap&#xff09; 1.概述 CAS的全称为Compare-And-Swap&#xff0c;直译就是对比交换。是一条CPU的原子指令&#xff0c;其作用是让CPU先进行比较两个值是否相等&#xff0c;然后原子地更新某个位置的值。经过调查发现&#xff0c;…...

Linux服务器配置系统安全加固方法

1. SSH空闲超时时间建议为: 600-900 解决方案: 在【/etc/ssh/sshd_config】文件中设置【ClientAliveInterval】设置为600到900之间 vim /etc/ssh/sshd_config #将 ClientAliveInterval 参数值设置为 900 2. 修改检查SSH密码修改最小间隔 解决方案: 在【/etc/login.defs】文件…...

Codeforces Round #850 (Div. 2, based on VK Cup 2022 - Final Round)(A~E)

t宝酱紫喜欢出这种分类讨论的题&#xff1f;&#xff01;A1. Non-alternating Deck (easy version)给出n张牌&#xff0c;按照题目给的顺序分给两人&#xff0c;问最后两人手中各有几张牌。思路&#xff1a;模拟。AC Code&#xff1a;#include <bits/stdc.h>typedef long…...

qt源码--信号槽

本篇主要从Qt信号槽的连接、断开、调用、对象释放等方面展开&#xff1b; 1.信号建立连接过程 connect有多个重载函数&#xff0c;主要是为了方便使用者&#xff0c;比较常用的有2种方式&#xff1a; a. QObject::connect(&timer, &QTimer::timeout, &loop, &am…...

RecycleView详解

listview缓存请看: listview优化和详解RecycleView 和 ListView对比&#xff1a;使用方法上ListView&#xff1a;继承重写 BaseAdapter&#xff0c;自定义 ViewHolder 与 converView优化。RecyclerView: 继承重写 RecyclerView.Adapter 与 RecyclerView.ViewHolder。设置 Layou…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...

命令行关闭Windows防火墙

命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)​方法二:CMD命令…...

FTXUI::Dom 模块

DOM 模块定义了分层的 FTXUI::Element 树&#xff0c;可用于构建复杂的终端界面&#xff0c;支持响应终端尺寸变化。 namespace ftxui {...// 定义文档 定义布局盒子 Element document vbox({// 设置文本 设置加粗 设置文本颜色text("The window") | bold | color(…...

【动态规划】B4336 [中山市赛 2023] 永别|普及+

B4336 [中山市赛 2023] 永别 题目描述 你做了一个梦&#xff0c;梦里有一个字符串&#xff0c;这个字符串无论正着读还是倒着读都是一样的&#xff0c;例如&#xff1a; a b c b a \tt abcba abcba 就符合这个条件。 但是你醒来时不记得梦中的字符串是什么&#xff0c;只记得…...