一、前言

上一节已经将raincat demo工程运行起来了,这一节来分析下raincat的源码

二、协调者启动过程

主要就是在启动类中通过如下代码来启动 netty

nettyService.start()

三、参与者启动过程

1.参与者启动时序图

参与者在启动过程中,主要做了如下4件事:

(1)保存SpringContext上下文

(2)通过加载spi,来使用用户自定义配置

(3)启动Netty客户端,与txManager进行连接,并且维持心跳。

(4)启动事务补偿任务,建表,定时补偿。

(5)启动事务事件发布器。

如下图:

2.保存Spring上下文

源码见  SpringBeanUtils 类,设置Spring 上下文,并提供spring  bean 的注册与获取方法。

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package com.raincat.core.helper; import org.springframework.context.ConfigurableApplicationContext; /**
* SpringBeanUtils.
* @author xiaoyu
*/
public final class SpringBeanUtils { private static final SpringBeanUtils INSTANCE = new SpringBeanUtils(); private ConfigurableApplicationContext cfgContext; private SpringBeanUtils() {
if (INSTANCE != null) {
throw new Error("error");
}
} /**
* get SpringBeanUtils.
* @return SpringBeanUtils
*/
public static SpringBeanUtils getInstance() {
return INSTANCE;
} /**
* acquire spring bean.
*
* @param type type
* @param <T> class
* @return bean
*/
public <T> T getBean(final Class<T> type) {
return cfgContext.getBean(type);
} /**
* register bean in spring ioc.
* @param beanName bean name
* @param obj bean
*/
public void registerBean(final String beanName, final Object obj) {
cfgContext.getBeanFactory().registerSingleton(beanName, obj);
} /**
* set application context.
* @param cfgContext application context
*/
public void setCfgContext(final ConfigurableApplicationContext cfgContext) {
this.cfgContext = cfgContext;
}
}

3.加载spi

    /**
* load spi.
*
* @param txConfig {@linkplain TxConfig}
*/
private void loadSpi(final TxConfig txConfig) {
//spi serialize
final SerializeProtocolEnum serializeProtocolEnum
= SerializeProtocolEnum.acquireSerializeProtocol(txConfig.getSerializer());
final ServiceLoader<ObjectSerializer> objectSerializers
= ServiceBootstrap.loadAll(ObjectSerializer.class);
final ObjectSerializer serializer =
StreamSupport.stream(objectSerializers.spliterator(), false)
.filter(s -> Objects.equals(s.getScheme(), serializeProtocolEnum.getSerializeProtocol()))
.findFirst().orElse(new KryoSerializer()); //spi RecoverRepository support
final CompensationCacheTypeEnum compensationCacheTypeEnum
= CompensationCacheTypeEnum.acquireCompensationCacheType(txConfig.getCompensationCacheType()); final ServiceLoader<TransactionRecoverRepository> recoverRepositories
= ServiceBootstrap.loadAll(TransactionRecoverRepository.class);
final TransactionRecoverRepository repository =
StreamSupport.stream(recoverRepositories.spliterator(), false)
.filter(r -> Objects.equals(r.getScheme(), compensationCacheTypeEnum.getCompensationCacheType()))
.findFirst().orElse(new JdbcTransactionRecoverRepository());
//将compensationCache实现注入到spring容器
repository.setSerializer(serializer);
SpringBeanUtils.getInstance().registerBean(TransactionRecoverRepository.class.getName(), repository);
}

(1)作用

SPI的全名为Service Provider Interface,该机制其实就是为接口寻找服务实现类

(2)如何使用

当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。
该文件里就是实现该服务接口的具体实现类。
而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。

八、参考资料

1.Java之SPI机制

分布式_事务_02_2PC框架raincat源码解析的更多相关文章

  1. 分布式事务_02_2PC框架raincat源码解析-启动过程

    一.前言 上一节已经将raincat demo工程运行起来了,这一节来分析下raincat启动过程的源码 主要包括: 事务协调者启动过程 事务参与者启动过程 二.协调者启动过程 主要就是在启动类中通过 ...

  2. 分布式事务_03_2PC框架raincat源码解析-事务提交过程

    一.前言 前面两节,我们已经将raincat的demo工程启动,并简单分析了下事务协调者与事务参与者的启动过程. 这一节,我们来看下raincat的事务提交过程. 二.事务提交过程概览 1.二阶段对应 ...

  3. 分布式_事务_01_2PC框架raincat快速体验1

    一.前言 关于2PC的理论知识请见:分布式_理论_03_2PC 这一节我们来看下github上一个优秀的2PC分布式事务开源框架的快速体验. 二.源码 源码请见: https://github.com ...

  4. 【安卓网络请求开源框架Volley源码解析系列】定制自己的Request请求及Volley框架源码剖析

    通过前面的学习我们已经掌握了Volley的基本用法,没看过的建议大家先去阅读我的博文[安卓网络请求开源框架Volley源码解析系列]初识Volley及其基本用法.如StringRequest用来请求一 ...

  5. 【安卓网络请求开源框架Volley源码解析系列】初识Volley及其基本用法

    在安卓中当涉及到网络请求时,我们通常使用的是HttpUrlConnection与HttpClient这两个类,网络请求一般是比较耗时,因此我们通常会在一个线程中来使用,但是在线程中使用这两个类时就要考 ...

  6. [源码解析] 并行分布式框架 Celery 之 Lamport 逻辑时钟 & Mingle

    [源码解析] 并行分布式框架 Celery 之 Lamport 逻辑时钟 & Mingle 目录 [源码解析] 并行分布式框架 Celery 之 Lamport 逻辑时钟 & Ming ...

  7. [源码解析] 深度学习分布式训练框架 horovod (5) --- 融合框架

    [源码解析] 深度学习分布式训练框架 horovod (5) --- 融合框架 目录 [源码解析] 深度学习分布式训练框架 horovod (5) --- 融合框架 0x00 摘要 0x01 架构图 ...

  8. [源码解析] PyTorch 分布式(17) --- 结合DDP和分布式 RPC 框架

    [源码解析] PyTorch 分布式(17) --- 结合DDP和分布式 RPC 框架 目录 [源码解析] PyTorch 分布式(17) --- 结合DDP和分布式 RPC 框架 0x00 摘要 0 ...

  9. [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器

    [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器 目录 [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器 0x0 ...

随机推荐

  1. su: warning: cannot change directory to : Permission denied ;-bash: bash_profile: Permission denied

    一.查看主目录权限对不对 1:问题描述 [root@ser6-52 ~]# su - mongodb su: warning: cannot change directory to /home/mon ...

  2. 20170524 委外采购的物料BOM

    目标:找委外采购订单BOM, 我的方法:1.直接在电脑中搜索关键字:2.到系统中找数据查询3.委外采购订单系统如何操作? 数据怎么做, 实施: 结果:MDBAEKET, "采购订单项目计划行 ...

  3. (转)fiddler使用简介--其三

    原文地址:http://www.cnblogs.com/miantest/p/7294620.html 我们知道Fiddler是位于客户端和服务器之间的代理,它能够记录客户端和服务器之间的所有 HTT ...

  4. gearman mysql持久化

    gearman 创建Mysql持久化队列的方式如下: 启动gearman,命令如下: gearmand命令: -b, –backlog=BACKLOG 连接请求队列的最大值 -d, –daemon D ...

  5. 自制Javascript浮动广告

    <%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb ...

  6. net-snmp配置文件snmp.conf

    master agentxagentaddress UDP:161sysLocation locationsysContact test@example.comsysName TestsysObjec ...

  7. 进程理论基础(Day32)

    背景知识 顾名思义,进程即一个软件正在进行的过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老的也是最重要的抽象概念之一.操作系统的其他 ...

  8. Django 进阶篇之 CSRF,COOIKE,SESSION

    1.CSRF(Cross Site Request Forgery, 跨站域请求伪造) CSRF 背景与介绍 CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网 ...

  9. iOS 11 Xcode9开发 新特性学习 (警告篇)

    最新版本SDK优化了开发体验,编译过程会提供更多提示警告,建议你修改.这些功能也可以自主选择用或者不用,当然,苹果喜欢你用他推荐的东西... 1 . @avalibale 语法,同步判断当前iOS系统 ...

  10. 在看 jquery 源码中发现的一些优化方向

    1. 避免使用 $.fn.each 或 $.each 因为它比原生的 for/while 真的会慢一些,循环次数越多差距越大. 另外,对象的 for-in 比 for 是要快一丢丢的,但数组的 for ...