当前位置: 首页 > 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…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...