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

Sharding-JDBC分库分表-自动配置与分片规则加载原理-3

Sharding JDBC自动配置的原理

与所有starter一样,shardingsphere-jdbc-core-spring-boot-starter也是通过SPI自动配置的原理实现分库分表配置加载,spring.factories文件中的自动配置类shardingsphere-jdbc-core-spring-boot-starter功不可没,他主要是自动创建了模式bean、事务类型bean和数据源bean,配置加载的过程可以归纳如下:

创建模式bean
创建数据源bean
创建事务类型扫描bean
ShardingSphereAutoConfiguration
ModeConfiguration
ShardingSphereDataSource
TransactionTypeScanner

其中,创建数据源bean时会根据不同的模式创建不同的bean,本地模式直接从配置文件中加载,配置中心模式就从配置中心加载。ShardingSphereAutoConfiguration的实现如下:

@Configuration
@ComponentScan("org.apache.shardingsphere.spring.boot.converter")
@EnableConfigurationProperties(SpringBootPropertiesConfiguration.class)
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
@RequiredArgsConstructor
public class ShardingSphereAutoConfiguration implements EnvironmentAware {private String databaseName;private final SpringBootPropertiesConfiguration props;private final Map<String, DataSource> dataSourceMap = new LinkedHashMap<>();/*** 模式配置** @return mode configuration*/@Beanpublic ModeConfiguration modeConfiguration() {return null == props.getMode() ? null : new YamlModeConfigurationSwapper().swapToObject(props.getMode());}/*** 单机模式:从本地配置中加载DataSource** @param rules rules configuration* @param modeConfig mode configuration* @return data source bean* @throws SQLException SQL exception*/@Bean@Conditional(LocalRulesCondition.class)@Autowired(required = false)public DataSource shardingSphereDataSource(final ObjectProvider<List<RuleConfiguration>> rules, final ObjectProvider<ModeConfiguration> modeConfig) throws SQLException {Collection<RuleConfiguration> ruleConfigs = Optional.ofNullable(rules.getIfAvailable()).orElseGet(Collections::emptyList);return ShardingSphereDataSourceFactory.createDataSource(databaseName, modeConfig.getIfAvailable(), dataSourceMap, ruleConfigs, props.getProps());}/*** 集群模式:从配置中心中加载DataSource** @param modeConfig mode configuration* @return data source bean* @throws SQLException SQL exception*/@Bean@ConditionalOnMissingBean(DataSource.class)public DataSource dataSource(final ModeConfiguration modeConfig) throws SQLException {return !dataSourceMap.isEmpty() ? ShardingSphereDataSourceFactory.createDataSource(databaseName, modeConfig, dataSourceMap, Collections.emptyList(), props.getProps()): ShardingSphereDataSourceFactory.createDataSource(databaseName, modeConfig);}/*** 事务类型扫描bean** @return transaction type scanner*/@Beanpublic TransactionTypeScanner transactionTypeScanner() {return new TransactionTypeScanner();}@Overridepublic final void setEnvironment(final Environment environment) {dataSourceMap.putAll(DataSourceMapSetter.getDataSourceMap(environment));databaseName = DatabaseNameSetter.getDatabaseName(environment);}
}

下面以单机模式出发点,理一下加载的过程。

@Bean
@Conditional(LocalRulesCondition.class)
@Autowired(required = false)
public DataSource shardingSphereDataSource(final ObjectProvider<List<RuleConfiguration>> rules, final ObjectProvider<ModeConfiguration> modeConfig) throws SQLException {Collection<RuleConfiguration> ruleConfigs = Optional.ofNullable(rules.getIfAvailable()).orElseGet(Collections::emptyList);// 通过ShardingSphereDataSourceFactory工厂创建数据源return ShardingSphereDataSourceFactory.createDataSource(databaseName, modeConfig.getIfAvailable(), dataSourceMap, ruleConfigs, props.getProps());
}

通过对源码的跟踪,可以发现,ShardingSphereDataSourceFactory.createDataSource创建数据源经历了如下的过程

创建数据源bean
new
创建上下文管理器
创建JDBC上下文
创建InstanceMetaData
根据mode调用
创建元数据上下文
创建数据库连接元数据
调用
加载分片规则
new
ShardingSphereAutoConfiguration
ShardingSphereDataSourceFactory.createDataSource
ShardingSphereDataSource
ShardingSphereDataSource.createContextManager
JDBCContext
InstanceMetaDataBuilderFactory.create
StandaloneContextManagerBuilder.build
MetaDataContextsFactory.create
ShardingSphereDatabasesFactory.create
ShardingSphereDatabase.create
DatabaseRulesBuilder.build
ShardingSphereDatabase

分片规则加载原理

分片规则、审计规则、key生成规则都是通过SPI的方式加载,自动配置类ShardingSphereAutoConfiguration中创建ShardingSphereDataSource的时候,会加载配置的分片规则,创建核心配置类ShardingRule,在ShardingRule的创建中会通过SPI的方式加载分片规则。加载的过程如下:

创建数据源bean
查询实例
通过SPI Class获取服务实例
Y:创建新的service实例
N:Map中获取service单例
创建分片规则
创建分片规则
创建核心分库分表规则
分片规则
Key生成规则
审计规则
通过工厂创建分片算法
获取注册的service
SPI方式获取service
通过工厂创建key生成算法
通过工厂创建审计算法
ShardingSphereAutoConfiguration
ShardingSphereDataSource
一系列加载...
DatabaseRulesBuilder.build
OrderedSPIRegistry.getRegisteredServices
ShardingSphereServiceLoader.getServiceInstances(spiClass)
带@SingletonSPI注解?
service.getClass().getDeclaredConstructor().newInstance()
SERVICES.getOrDefault(serviceInterface, Collections.emptyList())
ShardingRuleBuilder.build
new ShardingRule
ShardingAlgorithmFactory.newInstance
KeyGenerateAlgorithmFactory.newInstance
ShardingAuditAlgorithmFactory.newInstance
ShardingSphereAlgorithmFactory.createAlgorithm
TypedSPIRegistry.getRegisteredService
ShardingSphereServiceLoader.getServiceInstances(spiClass)

SPI核心实现类ShardingSphereServiceLoader中会将SPI接口进行Map缓存管理,需要时直接获取。如果Map中不存在,就通过反射的方式新建服务实例,具体实现源码如下:

public final class ShardingSphereServiceLoader {// 缓存service实例,// 缓存的Key,如://  org.apache.shardingsphere.sharding.spi.ShardingAlgorithm//  org.apache.shardingsphere.sharding.spi.KeyGenerateAlgorithm//  org.apache.shardingsphere.transaction.spi.ShardingSphereTransactionManagerprivate static final Map<Class<?>, Collection<Object>> SERVICES = new ConcurrentHashMap<>();/*** 注册服务实例** @param 服务接口*/public static void register(final Class<?> serviceInterface) {if (!SERVICES.containsKey(serviceInterface)) {SERVICES.put(serviceInterface, load(serviceInterface));}}private static <T> Collection<Object> load(final Class<T> serviceInterface) {Collection<Object> result = new LinkedList<>();for (T each : ServiceLoader.load(serviceInterface)) {result.add(each);}return result;}/*** 获取服务实例* * @param 服务接口* @param <T> 服务类型* @return 服务实例*/public static <T> Collection<T> getServiceInstances(final Class<T> serviceInterface) {return null == serviceInterface.getAnnotation(SingletonSPI.class) ? createNewServiceInstances(serviceInterface) : getSingletonServiceInstances(serviceInterface);}@SneakyThrows(ReflectiveOperationException.class)@SuppressWarnings("unchecked")private static <T> Collection<T> createNewServiceInstances(final Class<T> serviceInterface) {if (!SERVICES.containsKey(serviceInterface)) {return Collections.emptyList();}Collection<Object> services = SERVICES.get(serviceInterface);if (services.isEmpty()) {return Collections.emptyList();}Collection<T> result = new LinkedList<>();for (Object each : services) {// 通过反射新建实例result.add((T) each.getClass().getDeclaredConstructor().newInstance());}return result;}@SuppressWarnings("unchecked")private static <T> Collection<T> getSingletonServiceInstances(final Class<T> serviceInterface) {return (Collection<T>) SERVICES.getOrDefault(serviceInterface, Collections.emptyList());}
}

相关文章:

Sharding-JDBC分库分表-自动配置与分片规则加载原理-3

Sharding JDBC自动配置的原理 与所有starter一样&#xff0c;shardingsphere-jdbc-core-spring-boot-starter也是通过SPI自动配置的原理实现分库分表配置加载&#xff0c;spring.factories文件中的自动配置类shardingsphere-jdbc-core-spring-boot-starter功不可没&#xff0c…...

E8267D 是德科技矢量信号发生器

描述 最先进的微波信号发生器 安捷伦E8267D PSG矢量信号发生器是业界首款集成式微波矢量信号发生器&#xff0c;I/Q调制最高可达44 GHz&#xff0c;典型输出功率为23 dBm&#xff0c;最高可达20 GHz&#xff0c;对于10 GHz信号&#xff0c;10 kHz偏移时的相位噪声为-120 dBc/…...

Git git fetch 和 git pull 区别

git pull和git fetch的作用都是用于从远程仓库获取最新代码&#xff0c;但它们之间有一些区别。 git pull会自动执行两个操作&#xff1a;git fetch和git merge。它从远程仓库获取最新代码&#xff0c;并将其合并到当前分支中。 示例&#xff1a;运行git pull origin master会从…...

软件UI工程师工作的岗位职责(合集)

软件UI工程师工作的岗位职责1 职责&#xff1a; 1.负责产品的UI视觉设计(手机软件界面 网站界面 图标设计产品广告及 企业文化的创意设计等); 2.负责公司各种客户端软件客户端的UE/UI界面及相关图标制作; 3.设定产品界面的整体视觉风格; 4.参与产品规划构思和创意过程&…...

Mac系统Anaconda环境配置Python的json库

本文介绍在Mac电脑的Anaconda环境中&#xff0c;配置Python语言中&#xff0c;用以编码、解码、处理JSON数据的json库的方法&#xff1b;在Windows电脑中配置json库的方法也是类似的&#xff0c;大家可以一并参考。 JSON&#xff08;JavaScript Object Notation&#xff09;是一…...

Python数据分析与数据挖掘:解析数据的力量

引言&#xff1a; 随着大数据时代的到来&#xff0c;数据分析和数据挖掘已经成为许多行业中不可或缺的一部分。在这个信息爆炸的时代&#xff0c;如何从大量的数据中提取有价值的信息&#xff0c;成为了企业和个人追求的目标。而Python作为一种强大的编程语言&#xff0c;提供…...

我的私人笔记(安装hive)

1.hive下载&#xff1a;Index of /dist/hive/hive-1.2.1 或者上传安装包至/opt/software&#xff1a;rz或winscp上传 2.解压 cd /opt/software tar -xzvf apache-hive-1.2.1-bin.tar.gz -C /opt/servers/ 3.重命名 mv apache-hive-1.2.1-bin hive 4.配置环境变量 vi /etc/…...

【kubernetes】k8s部署APISIX及在KubeSphere使用APISIX

Apache APISIX https://apisix.apache.org/ 功能比nginx-ingress更强 本文采用2.5.0版本 https://apisix.apache.org/zh/docs/apisix/2.15/getting-started/ 概述内容来源于官方&#xff0c;学习于马士兵云原生课程 概述 Apache APISIX 是什么&#xff1f; Apache APISIX 是 …...

串口接收数据-控制LED灯

目标 通过串口接收数据&#xff0c;对数据分析&#xff0c;控制8个LED灯按照设定时间闪烁。 8个LED灯可以任意设计&#xff0c;是否闪烁。闪烁时间按ms计算&#xff0c;通过串口发送&#xff0c;可设置1~4,294,967,296ms&#xff0c;也就是4字节数据协议自拟&#xff0c;有数…...

python面试题合集(一)

python技术面试题 1、Python中的幂运算 在python中幂运算是由两个 **星号运算的&#xff0c;实例如下&#xff1a; >>> a 2 ** 2 >>> a 4我们可以看到2的平方输出结果为4。 那么 ^指的是什么呢&#xff1f;我们用代码进行演示&#xff1a; >>>…...

论文浅尝 | 利用对抗攻击策略缓解预训练语言模型中的命名实体情感偏差问题...

笔记整理&#xff1a;田家琛&#xff0c;天津大学博士&#xff0c;研究方向为文本分类 链接&#xff1a;https://ojs.aaai.org/index.php/AAAI/article/view/26599 动机 近年来&#xff0c;随着预训练语言模型&#xff08;PLMs&#xff09;在情感分类领域的广泛应用&#xff0c…...

springboot web开发springmvc自动配置原理

前言 我们也知道springboot启用springmvc基本不用做什么配置可以很方便就使用了但是不了解原理,开发过程中遇到点问题估计就比较头疼,不管了解的深不深入,先巴拉一番再说… 下面我们先看看官网…我的版本是2.3.2版本,发现官网改动也比较大…不同版本自己巴拉下吧,结构虽然变化…...

发表于《自然》杂志:语音转文本BCI的新突破实现62字/分钟的速度

语音脑机接口&#xff08;BCI&#xff09;是一项创新技术&#xff0c;通过用户的大脑信号在用户和某些设备之间建立通信通道&#xff0c;它们在恢复残疾患者的言语和通信能力方面具有巨大潜力。 早期的研究虽然很有希望&#xff0c;但尚未达到足够高的精度来解码大脑活动&…...

微软 Turing Bletchley v3视觉语言模型更新:必应搜索图片更精准

据微软新闻稿透露&#xff0c;在推出第三代Turing Bletchley视觉语言模型后&#xff0c;微软计划逐步将其整合到Bing等相关产品中&#xff0c;以提供更出色的图像搜索体验。这款模型最初于2021年11月面世&#xff0c;并在2022年秋季开始邀请用户测试。 凭借用户的反馈和建议&am…...

Ubuntu 22.04 x86_64 源码编译 pytorch-v2.0.1 笔记【2】编译成功

20230831继续&#xff1a; 当前状态 (pytorch-build) yeqiangyeqiang-MS-7B23:~/Downloads/src/pytorch$ pwd /home/yeqiang/Downloads/src/pytorch (pytorch-build) yeqiangyeqiang-MS-7B23:~/Downloads/src/pytorch$ python3 -V Python 3.10.6 (pytorch-build) yeqiangyeqi…...

IIR滤波器

IIR滤波器原理 IIR的特点是&#xff1a;非线性相位、消耗资源少。 IIR滤波器的系统函数与差分方程如下所示&#xff1a; 由差分方程可知IIR滤波器存在反馈&#xff0c;因此在FPGA设计时要考虑到有限字长效应带来的影响。差分方程中包括两个部分&#xff1a;输入信号x(n)的M节…...

【QT】使用qml的QtWebEngine遇到的一些问题总结

在使用qt官方的一些QML的QtWebEngine相关的例程的时候&#xff0c;有时在运行会报如下错误&#xff1a; WebEngineContext used before QtWebEngine::initialize() or OpenGL context creation failed 这个问题在main函数里面最前面加上&#xff1a; QCoreApplication::setAttr…...

230902-部署Gradio到已有FastAPI及服务器中

1. 官方例子 run.py from fastapi import FastAPI import gradio as grCUSTOM_PATH "/gradio"app FastAPI()app.get("/") def read_main():return {"message": "This is your main app"}io gr.Interface(lambda x: "Hello, …...

Ubuntu本地快速搭建web小游戏网站,公网用户远程访问【内网穿透】

文章目录 前言1. 本地环境服务搭建2. 局域网测试访问3. 内网穿透3.1 ubuntu本地安装cpolar内网穿透3.2 创建隧道3.3 测试公网访问 4. 配置固定二级子域名4.1 保留一个二级子域名4.2 配置二级子域名4.3 测试访问公网固定二级子域名 前言 网&#xff1a;我们通常说的是互联网&am…...

【LeetCode-中等题】199. 二叉树的右视图

文章目录 题目方法一&#xff1a;层序遍历取每一层最后一个元素方法二&#xff1a;深度优先搜索 题目 方法一&#xff1a;层序遍历取每一层最后一个元素 // 方法一 &#xff1a;层序 集合(取每层子集合最后一个元素)// List<List<Integer>> Rlist new ArrayList…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文通过代码驱动的方式&#xff0c;系统讲解PyTorch核心概念和实战技巧&#xff0c;涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...

Ubuntu系统多网卡多相机IP设置方法

目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机&#xff0c;交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息&#xff0c;系统版本&#xff1a;Ubuntu22.04.5 LTS&#xff1b;内核版本…...