Sharding-Jdbc 源码分析
上一篇文我们直接从sharding Jdbc的源码出发,讨论了sharding-Jdbc如何重写jdbc基础的四大基础类,现在重新从sharding-jdbc的example开始,一步一步打断点重新看一下jdbc如何建立 datasource的过程。
首先我们选用org.apache.shardingsphere.example.sharding.spring.boot.jpa
这里的测试方法,修改一下本地的配置文件,使得方法可以运行
然后我们在createDatesource这里打上断点可以看到传入的参数
createDatesource方法创建了一个新的类ShardingSphereDataSource
这个类创建的第一步就是初始化MetaDataContexts
类,而这个类是我们 org.apache.shardingsphere.infra
这个基础包内的一个基础类
我们这里来回顾一下infra包内的结构
shardingsphere-infra % tree -L 1
├── shardingsphere-infra-authority proxy权限配置
├── shardingsphere-infra-binder sql解析结果转换
├── shardingsphere-infra-common 重要的基本对象和工具
├── shardingsphere-infra-context 封装的上下文集合
├── shardingsphere-infra-datetime 时间服务
├── shardingsphere-infra-executor 引擎-执行引擎
├── shardingsphere-infra-merge 引擎-归并引擎
├── shardingsphere-infra-optimize 引擎-优化引擎,新加的
├── shardingsphere-infra-parser 引擎-解析引擎
├── shardingsphere-infra-rewrite 引擎-改写引擎
├── shardingsphere-infra-route
复制代码
singletonMap
首先处理了传入的datasouceMap参数,然后校验了XA_TRANSACTION_MANAGER_TYPE
(柔性事务类型)。
public ShardingSphereDataSource(final Map<String, DataSource> dataSourceMap, final Collection<RuleConfiguration> configurations, final Properties props) throws SQLException {
metaDataContexts = new MetaDataContextsBuilder(
Collections.singletonMap(DefaultSchema.LOGIC_NAME, dataSourceMap), Collections.singletonMap(DefaultSchema.LOGIC_NAME, configurations), props).build();
String xaTransactionMangerType = metaDataContexts.getProps().getValue(ConfigurationPropertyKey.XA_TRANSACTION_MANAGER_TYPE);
transactionContexts = createTransactionContexts(metaDataContexts.getDefaultMetaData().getResource().getDatabaseType(), dataSourceMap, xaTransactionMangerType);
}
复制代码
下文的代码中可以看到首先这个原数据上下文调用了MetaDataContextsBuilder
初始化了MetaDataContexts
MetaDataContextsBuilder
中含有非常多的初始化类,我们这里先讨论build
public StandardMetaDataContexts build() throws SQLException {
Map<String, ShardingSphereMetaData> mataDataMap = new HashMap<>(ruleConfigs.size(), 1);
Authentication authentication = buildAuthentication(users, mataDataMap);
for (String each : ruleConfigs.keySet()) {
mataDataMap.put(each, buildMetaData(each));
}
return new StandardMetaDataContexts(mataDataMap, executorEngine, authentication, props);
}
复制代码
初始化类初始化时候调用buildAuthentication
方法,然后在方法内调用PrivilegeBuilder
PrivilegeBuilder
内根据缓存和传入的user信息进行用户权限的校验和初始化,这里细节太多就不更多的讨论了
初始化完用户权限以后,开始MetaDataContextsBuilder 再初始化MetaData:
private ShardingSphereMetaData buildMetaData(final String schemaName) throws SQLException {
Map<String, DataSource> dataSourceMap = dataSources.get(schemaName);
Collection<RuleConfiguration> ruleConfigs = this.ruleConfigs.get(schemaName);
DatabaseType databaseType = getDatabaseType(dataSourceMap);
Collection<ShardingSphereRule> rules = ShardingSphereRulesBuilder.build(ruleConfigs, databaseType, dataSourceMap, schemaName);
ShardingSphereRuleMetaData ruleMetaData = new ShardingSphereRuleMetaData(ruleConfigs, rules);
return new ShardingSphereMetaData(schemaName, buildResource(databaseType, dataSourceMap), ruleMetaData, buildSchema(schemaName, databaseType, dataSourceMap, rules));
}
复制代码
可以看到首先取了datasource和ruleconfig中的参数以后,使用ShardingSphereRulesBuilder
进行规则的初始化。
然后对数据库的类型进行了判断
private DatabaseType getDatabaseType(final Map<String, DataSource> dataSourceMap) {
DatabaseType result = null;
for (DataSource each : dataSourceMap.values()) {
DatabaseType databaseType = getDatabaseType(each);
Preconditions.checkState(null == result || result == databaseType, String.format("Database type inconsistent with '%s' and '%s'", result, databaseType));
result = databaseType;
}
return null == result ? DatabaseTypeRegistry.getDefaultDatabaseType() : result;
}
private DatabaseType getDatabaseType(final DataSource dataSource) {
try (Connection connection = dataSource.getConnection()) {
return DatabaseTypeRegistry.getDatabaseTypeByURL(connection.getMetaData().getURL());
} catch (final SQLException ex) {
return null;
}
}
复制代码
初始化元数据上下文以后,createDataSource会调用ShardingTransactionManagerEngine
初始化事务上下文,需要配置事务以后才会实现。
private TransactionContexts createTransactionContexts(final DatabaseType databaseType, final Map<String, DataSource> dataSourceMap, final String xaTransactionMangerType) {
ShardingTransactionManagerEngine engine = new ShardingTransactionManagerEngine();
engine.init(databaseType, dataSourceMap, xaTransactionMangerType);
return new StandardTransactionContexts(Collections.singletonMap(DefaultSchema.LOGIC_NAME, engine));
}
复制代码
下文再进行讨论。 Shardingsphere如何整合Atomikos对XA分布式事务的支持
如果不配置,这里就直接结束创建ShardingSphereDataSource
的过程。
近期评论