简介
在前几篇文中,我们基于源码就ShardingSphere的核心功能给运行了一遍,本篇文章开始,我们开始探索源码,看看ShardingSphere是如何进行工作的
概览
开始之前,我们先思考这次探索的疑点:
- 1.ShardingSphere是如何加载我们配置的多个数据库源的?
- 2.ShardingSphere是如何将语句写到不同的数据源的?
带着问题去探索,虽然可能得不到答案,但起码有个方向
基于我们JDBC探索的文章,打上相关的断点,开始我们的探索之旅
源码探索
1.寻找ShardingSphere JDBC 的入口
在下面代码中的init和process打上断点,看看能不能通过程序调用栈找到蛛丝马迹
public final class ExampleExecuteTemplate {
public static void run(final ExampleService exampleService) throws SQLException {
try {
exampleService.initEnvironment();
exampleService.processSuccess();
} finally {
exampleService.cleanEnvironment();
}
}
}
exampleService.initEnvironment() 进来以后,调用栈空空如也,啥也没有,看来我们第一个探索如果加载多个配置的数据源的目的告吹了
但还是继续Debug下去,竟然全是Ibatis相关的东西,没有Debug到ShardingSphere相关的代码,安慰自己,正常现象
继续探索:exampleService.processSuccess(),来到下面的相关语句的插入、查询等相关的操作,在insertData()打上断点
public class OrderServiceImpl implements ExampleService {
@Override
@Transactional
public void processSuccess() throws SQLException {
System.out.println("-------------- Process Success Begin ---------------");
List<Long> orderIds = insertData();
printData();
deleteData(orderIds);
printData();
System.out.println("-------------- Process Success Finish --------------");
}
}
基于之前尝试没有收获,这次不得不小心翼翼,跟着函数调用不断的深入下去
MapperProxy.class,执行下面的方法,进行跟下去:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
}
if (this.isDefaultMethod(method)) {
return this.invokeDefaultMethod(proxy, method, args);
}
} catch (Throwable var5) {
throw ExceptionUtil.unwrapThrowable(var5);
}
MapperMethod mapperMethod = this.cachedMapperMethod(method);
// 从这里进入
return mapperMethod.execute(this.sqlSession, args);
}
来到下面的函数
public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
Object param;
switch(this.command.getType()) {
case INSERT:
param = this.method.convertArgsToSqlCommandParam(args);
// 从这里进入,跟踪insert方法
result = this.rowCountResult(sqlSession.insert(this.command.getName(), param));
break;
case UPDATE:
......
}
其中我们看到了熟悉的数据库相关的参数:SqlSession sqlSession,我们调用堆栈,查看其内容,如下图:
数据库名称竟然是 logic_db,想到秦老师讲课时说ShardingSphere UI中也能用JDBC,只是它的名称是