seata源碼分析(03)_創建代理的過程

seata提供了ProxyUtil工具類為事務組件創建代理對象,在spring環境中,seata提供了GlobalTransactionScanner類和SeataAutoDataSourceProxyCreator為組件創建AOP代理,本文重點分析這兩個類。

ProxyUtil

io.seata.integration.tx.api.util.ProxyUtil類。

public class ProxyUtil {private static final Map<Object, Object> PROXYED_SET = new HashMap<>();public static <T> T createProxy(T target) {return createProxy(target, target.getClass().getName());}public static <T> T createProxy(T target, String beanName) {try {synchronized (PROXYED_SET) {if (PROXYED_SET.containsKey(target)) {return (T) PROXYED_SET.get(target);}// 使用InterfaceParser獲取與target對應的ProxyInvocationHandler// 1. GlobalTransactionalInterceptorHandler// 2. TccActionInterceptorHandler// 內部檢查@GlobalTransactional、@GlobalLock、// @TwoPhaseBusinessAction等注解,來判斷是否需要創建代理ProxyInvocationHandler proxyInvocationHandler =DefaultInterfaceParser.get().parserInterfaceToProxy(target, beanName);if (proxyInvocationHandler == null) {return target;}// 創建代理對象// 把proxyInvocationHandler注入到攔截邏輯中// DefaultInvocationHandler實現了java InvocationHandler接口// invoke方法會執行proxyInvocationHandler的代理邏輯T proxy = (T) new ByteBuddy().subclass(target.getClass()).method(isDeclaredBy(target.getClass())).intercept(InvocationHandlerAdapter.of(new DefaultInvocationHandler(proxyInvocationHandler, target))).make().load(target.getClass().getClassLoader()).getLoaded().getDeclaredConstructor().newInstance();PROXYED_SET.put(target, proxy);return proxy;}} catch (Throwable t) {throw new RuntimeException("error occurs when create seata proxy", t);}}
}

DefaultInvocationHandler

public class DefaultInvocationHandler implements InvocationHandler {private ProxyInvocationHandler proxyInvocationHandler;private Object delegate;public DefaultInvocationHandler(ProxyInvocationHandler proxyInvocationHandler, Object delegate) {this.proxyInvocationHandler = proxyInvocationHandler;this.delegate = delegate;}// 動態代理邏輯@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {InvocationWrapper invocation = new DefaultInvocationWrapper(proxy, delegate, method, args);Object result;if (proxyInvocationHandler != null) {result = proxyInvocationHandler.invoke(invocation);} else {result = invocation.proceed();}return result;}
}

GlobalTransactionScanner

繼承了spring的AbstractAutoProxyCreator類:

  • 初始化TM和RM客戶端
  • 為seata的事務組件創建AOP代理

initClient方法創建TM和RM客戶端

使用seata提供的TMClient和RMClient工具欄初始化TM、RM客戶端:

private void initClient() {// ...if (StringUtils.isNullOrEmpty(applicationId) || StringUtils.isNullOrEmpty(txServiceGroup)) {throw new IllegalArgumentException(String.format("applicationId: %s, txServiceGroup: %s", applicationId, txServiceGroup));}// 創建TmNettyRemotingClientTMClient.init(applicationId, txServiceGroup, accessKey, secretKey);// 創建RmNettyRemotingClientRMClient.init(applicationId, txServiceGroup);// 優雅關閉客戶端registerSpringShutdownHook();
}

wrapIfNecessary方法創建AOP代理

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {// do checkersif (!doCheckers(bean, beanName)) {return bean;}try {synchronized (PROXYED_SET) {if (PROXYED_SET.contains(beanName)) {return bean;}interceptor = null;// 和ProxyUtil工具類一樣ProxyInvocationHandler proxyInvocationHandler =DefaultInterfaceParser.get().parserInterfaceToProxy(bean, beanName);// 如果proxyInvocationHandler為null表示不需要AOP代理if (proxyInvocationHandler == null) {return bean;}// AdapterSpringSeataInterceptor實現了MethodInterceptor接口// 用來封裝spring aop的代理攔截邏輯// 這是spring aop的原理,此處不展開分析interceptor = new AdapterSpringSeataInterceptor(proxyInvocationHandler);if (!AopUtils.isAopProxy(bean)) {// 如果bean不是一個代理對象則使用父類方法創建代理對象bean = super.wrapIfNecessary(bean, beanName, cacheKey);} else {// 如果bean已經是一個代理對象// 則需要將事務攔截邏輯添加到代理通知集AdvisedSupport advised = SpringProxyUtils.getAdvisedSupport(bean);Advisor[] advisor = buildAdvisors(beanName, getAdvicesAndAdvisorsForBean(null, null, null));int pos;for (Advisor avr : advisor) {pos = findAddSeataAdvisorPosition(advised, avr);advised.addAdvisor(pos, avr);}}PROXYED_SET.add(beanName);return bean;}} catch (Exception exx) {throw new RuntimeException(exx);}
}

AdapterSpringSeataInterceptor

public class AdapterSpringSeataInterceptor implements MethodInterceptor, SeataInterceptor, Ordered {private ProxyInvocationHandler proxyInvocationHandler;public AdapterSpringSeataInterceptor(ProxyInvocationHandler proxyInvocationHandler) {this.proxyInvocationHandler = proxyInvocationHandler;}@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {AdapterInvocationWrapper adapterInvocationWrapper = new AdapterInvocationWrapper(invocation);Object result = proxyInvocationHandler.invoke(adapterInvocationWrapper);return result;}@Overridepublic int getOrder() {return proxyInvocationHandler.getOrder();}@Overridepublic void setOrder(int order) {proxyInvocationHandler.setOrder(order);}@Overridepublic SeataInterceptorPosition getPosition() {return proxyInvocationHandler.getPosition();}@Overridepublic String toString() {return proxyInvocationHandler.getClass().getName();}
}

SeataAutoConfiguration配置類

用來裝配GlobalTransactionScanner組件。

SeataAutoDataSourceProxyCreator

在spring環境中,將原始的DataSource保證為SeataDataSourceProxy對象。

SeataDataSourceAutoConfiguration配置類

用來裝配SeataAutoDataSourceProxyCreator組件。

ProxyInvocationHandler

用來封裝代理的攔截邏輯。

接口定義

public interface ProxyInvocationHandler extends SeataInterceptor {Set<String> getMethodsToProxy();// 代理攔截邏輯Object invoke(InvocationWrapper invocation) throws Throwable;SeataInterceptorPosition getPosition();
}

實現類

ProxyInvocationHandler|-- AbstractProxyInvocationHandler|-- GlobalTransactionalInterceptorHandler|-- TccActionInterceptorHandler

AbstractProxyInvocationHandler

使用模板方法封裝通用的代理檢查邏輯:

public abstract class AbstractProxyInvocationHandler implements ProxyInvocationHandler {// 子類實現具體的代理邏輯protected abstract Object doInvoke(InvocationWrapper invocation) throws Throwable;protected int order = Integer.MAX_VALUE;@Overridepublic Object invoke(InvocationWrapper invocation) throws Throwable {if (CollectionUtils.isNotEmpty(getMethodsToProxy()) &&!getMethodsToProxy().contains(invocation.getMethod().getName())) {return invocation.proceed();}return doInvoke(invocation);}// 其他方法 略
}

GlobalTransactionalInterceptorHandler

The type Global transactional interceptor handler.

處理@GlobalTransactional和@GlobalLock注解。

TccActionInterceptorHandler

處理@TwoPhaseBusinessAction注解。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/21566.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/21566.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/21566.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【中年危機】程序猿自救指南

中年危機&#xff0c;一個聽起來就充滿挑戰的詞匯&#xff0c;它不僅僅是一個年齡的標記&#xff0c;更是一個個人成長和職業發展的轉折點。 構架個人品牌&#xff1a; 學會打造IP個人品牌是職業生涯中的重要資產。在中年時期&#xff0c;你已經積累了豐富的經驗和知識&#x…

golang的http客戶端封裝

簡介 net/http 是 Go 語言標準庫的一部分&#xff0c;它提供了創建 HTTP 客戶端和服務器的能力。這個包通過簡化與 HTTP 協議的交互&#xff0c;讓開發者能夠方便地構建 HTTP 請求和響應&#xff0c;以及處理路由等任務。 本文以 net/http 包作為底層&#xff0c;封裝一個包含…

HTCC電路板是什么,有哪些主要應用領域

HTCC英文名稱是High-Temperature Co-Fired Ceramic&#xff0c;又稱高溫共燒多層陶瓷基板。因其具有導熱系數高、耐熱性好、熱膨脹系數小、機械強度高、絕緣性好、耐腐蝕等優勢&#xff0c;是保持高速增加的PCB線路板之一。 SPEA作為專業電路板測試設備方案服務商&#xff0c;公…

FY-SA-20237·8-WhyWeSpin

Translated from the Scientific American, July/August 2023 issue. Why We Spin (我們為什么旋轉) Primates may play with reality by twirling around 翻譯&#xff1a;靈長類動物有能力通過旋轉或旋轉運動來操縱或扭曲他們對現實的感知。 解釋&#xff1a; “Primates”…

Java生成指定長度驗證碼

生成指定長度驗證碼的簡單思路在Java中通常涉及以下幾個步驟&#xff1a; 1、定義字符池&#xff1a; 首先&#xff0c;需要定義一個包含所有可能字符的字符串&#xff0c;這個字符池通常包括數字(0-9)、大寫字母(A-Z)、小寫字母(a-z)。 例如&#xff1a; String chars "…

【開發心得】三步本地化部署llama3大模型

目錄 第一步&#xff1a;啟動ollama 第二步&#xff1a;啟動dify 第三步&#xff1a;配置模型&#xff08;截圖&#xff09; 最近llama3很火&#xff0c;本文追擊熱點&#xff0c;做一個本地化部署的嘗試&#xff0c;結果還成功了&#xff01; 當然也是站在別人的肩膀上&…

【運維項目經歷|027】PXE自動化部署與管理平臺

&#x1f341;博主簡介&#xff1a; &#x1f3c5;云計算領域優質創作者 &#x1f3c5;2022年CSDN新星計劃python賽道第一名 &#x1f3c5;2022年CSDN原力計劃優質作者 &#x1f3c5;阿里云ACE認證高級工程師 &#x1f3c5;阿里云開發者社區專…

Nginx企業級負載均衡:技術詳解系列(18)—— 作為上傳服務器

你好&#xff0c;我是趙興晨&#xff0c;97年文科程序員。 在上一期的技術分享中&#xff0c;我們探討了如何高效搭建Nginx下載服務器&#xff0c;并討論了長連接優化策略。那么今天&#xff0c;咱們進一步了解Nginx的另一面——作為上傳服務器的配置技巧。 作為上傳服務器&a…

怎么做好企業短信服務呢?(文字短信XML接口示例)

企業短信服務已經成為各行各業都信賴的行業推廣方式之一&#xff0c;并且短信行業也與時俱進的發展著&#xff0c;隨之而來的就是市場上短信平臺的數量也隨之增多。那么怎么在魚龍混雜的短信行業中選擇適合自己的企業短信服務平臺呢&#xff1f;企業短信服務平臺又適用于哪些應…

Django的PATH路徑轉換器

本書1-7章樣章及配套資源下載鏈接: https://pan.baidu.com/s/1OGmhHxEMf2ZdozkUnDkAkA?pwdnanc 源碼、PPT課件、教學視頻等&#xff0c;可以從前言給出的下載信息下載&#xff0c;大家可以評估一下。 在Django框架中&#xff0c;默認內置了一組PATH路徑轉換器&#xff0c;具…

第一篇【傳奇開心果系列】AI工業應用經典算法和Python示例:基于AI的智能制造技術經典算法與Python實踐

傳奇開心果博文系列 系列博文目錄AI工業應用經典算法和Python示例系列 博文目錄前言一、AI在智能制造方面的應用場景介紹二、基于AI的智能制造技術經典算法介紹三、支持向量機機器學習算法Python示例代碼四、隨機森林機器學習算法Python示例代碼五、深度學習算法Python示例代碼…

linux指令-高階指令用法

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、pandas是什么&#xff1f;二、使用步驟 1.引入庫2.讀入數據總結 前言 linux操作系統的環境變量的使用基礎需要先了解 提示&#xff1a;以下是本篇文章正文…

【linux】(2)文件內容排序sort

sort 是一個用于排序文件內容的命令行工具&#xff0c;在 Linux 和 Unix 系統中非常常用。 基本用法 sort [OPTION]... [FILE]...常用選項 按數值排序 -n sort -n filename例子&#xff1a;對包含數值的文件進行排序。 按字典順序排序 -d sort -d filename例子&#xff1…

大宋咨詢(深圳酒店神秘顧客調查)酒店客房神秘人體驗調查內容

酒店客房神秘檢查內容&#xff0c;是酒店管理中至關重要的環節。通過專業的神秘顧客對客房進行細致入微的檢查&#xff0c;可以確保客房的清潔度、設施設備的完好性以及服務質量等方面達到高標準&#xff0c;幫助他們更好地了解客戶的需求和滿意度&#xff0c;從而提高服務質量…

Facebook開戶|Facebook公共主頁疑難雜癥詳解

??要要切克鬧&#xff0c;公共主頁我來道...哈嘍呀家人們中午好&#xff0c;上一次學習還是在上一次..hhh相信很多家人在做Facebook的時候總會遇到各種各樣匪夷所思的bug&#xff01;經常被搞心態吧&#xff01;那么咱們今天呢就來總結一下各類的bug以及解決方法&#xff0c;…

InvokeAI學習教程三:換臉

啟動InvokeAI&#xff0c;我們先生成一張圖&#xff1a; 在正向提示詞里輸入&#xff1a;Avant-garde couture, tactile textures, vogue aesthetics, vibrant color palette, intricate embroidery details, dramatic silhouettes 生成一張高貴夫人的圖像&#xff0c; 或者你從…

標準發布 | 廢水處理減污降碳協同評估指南(碳中和標準)

本文件主編單位&#xff1a;北京林業大學、北京交通大學、中國電建集團華東勘測設計研究院有限公司、 眉山市城投中恒能環保科技有限公司、 中華環保聯合會水環境治理專業委員會。 本文件參編單位&#xff1a;中國市政工程中南設計研究總院有限公司、湖北君集環境科技股份有 公…

C++ B (1124) : 斐波那契數列第n項Plus

文章目錄 一、題目描述二、參考代碼 一、題目描述 二、參考代碼 #include <iostream> #include <vector>using namespace std;const long long MOD 1e9 7; // 取模的值// 定義矩陣類 class Matrix { public:vector<vector<long long>> data;// 構造…

JavaWeb項目規范開發流程詳細分解

在JavaWeb項目開發中&#xff0c;遵循規范化的開發流程和最佳實踐可以提高代碼的可維護性、可擴展性和團隊協作效率。規范化的開發流程主要從下面幾個方面進行&#xff1a; 1. 項目結構 分層架構&#xff1a;典型的分層架構包括表示層&#xff08;Controller&#xff09;、業…

字節裁員!開啟裁員新模式。。

最近&#xff0c;互聯網圈不太平&#xff0c;裁員消息此起彼伏。而一向以“狼性文化”著稱的字節跳動&#xff0c;卻玩起了“低調裁員”&#xff0c;用一種近乎“溫柔”的方式&#xff0c;慢慢擠掉“冗余”的員工。 “細水長流”&#xff1a;裁員新模式&#xff1f; 不同于以往…