1. 程式人生 > >shardingsphere多數據源(springboot + mybatis+shardingsphere+druid)

shardingsphere多數據源(springboot + mybatis+shardingsphere+druid)

names inf 讀取 直接 sql 個數 mage 源配置 actor

org.springframeword.boot:spring-boot-starer-web: 2.0.4release

io.shardingsphere:sharding-jdbc-spring-boot-starter:3.0.0M3

org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.1

com.alibaba:druid-spring-boot-starter:1.1.9

由於項目需要,走了一波sharding jdbc多數據源配置,算是實戰演練了,此處記錄下踩過的坑。

代碼githut地址(https://github.com/autLory/test_sharding_pro),閹割版,去掉了與項目相關的東西,剩一些核心配置文件。

1,初始版本參考網上找各路大佬的博客資料寫出來的,配置了兩個數據源,然後在DataSourceConfig裏面分別初始化,基本實現分庫分表,主庫的分表策略在配置文件裏面配置,分庫的分表策略是在DataSourceConfig文件裏面初始化的時候配置手動寫ShardingRuleConfiguration然後加到ShardingDataSource裏面的(其實好一些的處理方法應該是都寫在配置文件裏面的,但是我沒做出來)。兩個DataSourceConfig文件分別初始化自己的數據源,mapper,xmlmapper,基本就完成了最初的版本。啟動時的時候去除掉Spring boot自帶的DataSourceAutoConfiguration文件。

2,初始版本完成之後,發現的第一個問題就是以前項目裏面寫的一個mybatis的攔截器失效了,攔截器的作用是攔截mybatis所有的insert ,update操作,添加一些業務字段,沒改多數據源之前是正常使用的,改了之後發現失效了,然後debug模式啟動發現攔截器確實是已經初始化過了,至於為什麽沒有生效,不知道。

解決思路:看源碼了,先找到前面去除掉的DataSourceAutoConfiguration文件,看看源碼,好像跟mybatis沒什麽關系,然後搜了下spring boot自動配置mybatis的初始化過程找到了MybatisAutoConfiguration文件,也就是mybatis的初始化配置文件,技術分享圖片

,AutoConfigAfter,字面理解執行於參數的class文件初始化之後,這個類裏面有個構造函數如下技術分享圖片

看起來好像找到一個跟攔截器有點關系的了,然後看看下面哪個地方被調用,如下:

技術分享圖片

在初始化SqlSessionFactory的時候會把攔截器添加到實例裏面,對比自己的Config文件,少了這麽一步,所以攔截器初始化了但是沒有生效時因為沒有添加到mybatis的實例裏面。

對應的改一下自己的配置文件,把interceptor加進去,再啟動測試,正常使用,搞定。

3 ,後續發現的第二個問題,druid的sql監控沒有了。為啥沒有了,不知道,繼續找原因改唄。

第一個猜測,druid相關的配置沒有生效, 又開始debug配置文件,發現了一個問題

技術分享圖片

此處DataSource初始化是直接調用DataSourceBuilder的.build方法初始化的,沒有任何參數,好吧,再看看DataSourceBuilder的代碼技術分享圖片

技術分享圖片

技術分享圖片

這個地方會去獲取DataSource的類型,然後結果拿到的就是HikariDataSource,鬼鬼,怪不得沒sql監控了,初始化出來的DataSource壓根就不是DruidDataSource,原因找到了,繼續改了,怎麽改了,先看sharding初始化DataSource的源碼,實際上Sharding jdbc的DataSource初始化是根據配置文件裏面type屬性來的,代碼在SpringBootConfiguration文件

技術分享圖片

這個地方在初始化DataSourceMap的時候會找到配置文件裏面 sharding.jdbc.datasource.names值對應的數據源,然後配置對應屬性

看代碼會發現這給放主要會調用兩個方法

一個是public static <T> T handle(final Environment environment, final String prefix, final Class<T> targetClass)方法

該方法作用是將當前environment下的配置文件裏面前綴為prefix的屬性轉換為一個targetClass對象

代碼裏面就是將前面為sharding.jdbc.datasource.ds的屬性轉換為一個map對象

第二個方法為DataSource getDataSource(final String dataSourceClassName, final Map<String, Object> dataSourceProperties)

源碼如下,

技術分享圖片

意思是先找到DataSource類型的class對象,然後循環前面獲取到的map對象,利用反射找到每一個key對應的set方法,將value值作為set方法的參數賦值給實例化出來的對象,然後將這個對象返回給上層的DataSouce初始化方法。這就實現了根據配置文件類實例化不同類型的DataSource實例。

而實際上我這邊是有問題的,項目確認使用druid連接池,所以我沒有把這些方法都copy到自己代碼裏面,而是在自己的DataSourceConfig文件裏面直接初始化一個DruidDataSource實例返回,初始化的時候直接讀取配置文件的各個屬性值賦值。改好之後再次啟動測試,就可以正常啟動druid的sql監控了。

以上!

shardingsphere多數據源(springboot + mybatis+shardingsphere+druid)