spring-jdbc之AbstractRoutingDataSource源碼解析

翻看之前springboot集成的mybatis讀寫分離,發現還有些疏漏 ,有的還不甚理解,於是翻看下源碼;

讀寫分離 主要就是數據路由的時候重寫roundRobinDataSouceProxy方法 ,roundRobinDataSouceProxy中最重要的是 AbstractRoutingDataSource類中的一個抽象方法determineCurrentLookupKey()

下面我們來看下AbstractRoutingDataSource類

 /**
     * 把所有數據庫都放在路由中
     * @return
     */
    @Bean(name="roundRobinDataSouceProxy")
    public AbstractRoutingDataSource roundRobinDataSouceProxy() {

        Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
        //把所有數據庫都放在targetDataSources中,注意key值要和determineCurrentLookupKey()中代碼寫的一至,
        //否則切換數據源時找不到正確的數據源
        targetDataSources.put(DataSourceType.write.getType(), writeDataSource);
        targetDataSources.put(DataSourceType.read.getType(), readDataSource);
 
 
        //路由類,尋找對應的數據源
        AbstractRoutingDataSource proxy = new AbstractRoutingDataSource(){
            
            @Override
            protected Object determineCurrentLookupKey() {
                
                return null;
            }
        };
	
        proxy.setDefaultTargetDataSource(writeDataSource);//默認庫
	////設置數據源映射
        proxy.setTargetDataSources(targetDataSources);
        return proxy;
    }

AbstractRoutingDataSource源碼
 

public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean{
  public Connection getConnection() throws SQLException {
        return this.determineTargetDataSource().getConnection();
    }
 protected DataSource determineTargetDataSource() {
        Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
	//引用抽象方法
        Object lookupKey = this.determineCurrentLookupKey();
        DataSource dataSource = (DataSource)this.resolvedDataSources.get(lookupKey);
        if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
            dataSource = this.resolvedDefaultDataSource;
        }

        if (dataSource == null) {
            throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
        } else {
            return dataSource;
        }
    }

        protected abstract Object determineCurrentLookupKey();

AbstractRoutingDataSource源碼中有個Object lookupKey = this.determineCurrentLookupKey();

在spring源碼中很常見的引用 抽象類中的方法引用抽象方法的實現;

最核心的就determineCurrentLookupKey方法實現, 返回一個datasource實例枚舉key,然後當前resolvedDataSources中獲取key對應的數據源,從而完成,數據源的動態切換。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章