动态数据源-SpringManagedTransaction&&AbstractRoutingDataSource 源码解析过程

动态数据源-源码解析过程

这其中需要mybatis的一些知识,进行一次debug调试,来查看过程。
在这里插入图片描述
在我们需要决定的地方打上断点,发送一次请求,我们先不要着急查看往下执行,先看一下调用栈已经调用了哪些方法并处于哪些类中。
在这里插入图片描述
如果看过mybatis源码,那么对上面的流程其实有一定的了解。接着进行断点的执行:在这里插入图片描述
这里回到了DynamicDataSource ,因为我们的 DynamicDataSource 是继承AbstractRoutingDataSource 的,并重写了AbstractRoutingDataSource 的钩子方法。这里我们的resolvedDataSources是在spring启动的时候初始化放进去的我们自定义的一些数据源,现在通过这个注解上的key拿到。感兴趣可以在DynamicDataSourceConfig中打断点在spring启动的时候去查看一次初始化过程。
在这里插入图片描述
接下来就回到我们的getConnection方法:
在这里插入图片描述
由于决定了使用哪一个数据源那么就从返回的数据源中调用getConnection方法,这里我使用的是com.zaxxer.hikari.HikariDataSource#getConnection()方法。接着执行:
在这里插入图片描述
这里是一个静态方法调用的是fetchConnection(DataSource dataSource),通过传入的DataSource参数去获取connection,这个dataSource其实就是我们配置的DynamicDataSource,那么问题来了这个dataSource是从哪里传过来的?我们需要找到他的源头,这里留个疑问。
在这里插入图片描述
上面的TransactionSynchronizationManager是一个事务同步器,在这里忽略不用管它,我们可以看到,dataSource仍然是由方法传进来的参数,并且类型仍然是我们自己配置的数据源DynamicDataSource。那我们接着往下看。
在这里插入图片描述
dataSource类型仍然没有变,继续往下执行。
在这里插入图片描述
现在我们可以看到SpringManagedTransaction传入了我们的DynamicDataSource,可以看到DynamicDataSource已经初始化到SpringManagedTransaction,那么SpringManagedTransaction是怎么找到我们的DynamicDataSource呢?留个疑问,我们看看SpringManagedTransaction的注解:
在这里插入图片描述
大概意思是SpringManagedTransaction处理JDBC的连接的生命周期,它从Spring的事务管理器中获取连接,并在不再需要时将连接返回给它。

如果Spring的事务处理是开启的,它将不对所有提交/回滚/关闭调用进行操作,将有Spring的事务管理器来处理。如果不是,它就仅仅为为普通的JdbcTransaction。

我们再来看看openConnection的注解:
在这里插入图片描述
从Spring事务管理器获取连接,并发现该事务是否应该管理连接或让连接到Spring。

它还读取autocommit设置,因为当使用Spring Transaction时,MyBatis认为autocommit总是false,并且总是调用commit/rollback,所以我们需要对调用进行无操作。我们接着往下看:
在这里插入图片描述
在这里插入图片描述

基本上下面的内容就是mybatis的内容了。所有我们基本上可以有个大致的了解:SpringManagedTransaction是一个关键,那我们回到初始化,看看我们的DynamicDataSource是如何注入到SpringManagedTransaction的。

SpringManagedTransaction

在SpringManagedTransaction有一个构造方法,我们在此打下断点,启动项目。但是启动后,并没有触发断点,我意识到可能这个是在请求中触发的。尝试一次结果如下:
在这里插入图片描述
这一步并不能看出什么,我们接着往下走一步:
在这里插入图片描述
终于我们看到了一个很熟悉的名字:DefaultSqlSessionFactory并且获取我们的Environment内配置好的DataSource,其实就对应上了:
在这里插入图片描述
在这里我们看一下调用栈:
在这里插入图片描述
其实就对应上了,在开启Session的时候,会去读取配置,这样我们的配置就会生效了。

既然都到这里了那么我们再往下走一走,一直走到我们的方法生效。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
进入invoke后,就走到了我们之前的:
在这里插入图片描述
所以呢?我们其实可以很容易的看出,这里代理的方法其实是走了我们的自定义配置里的方法,这样就和前文对应上了。
在这里插入图片描述
我们这里result其实就已经从连接里面查出数据了,被代理的方法是如下:
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值