Spring多数据源配置系列(二)——AbstractRoutingDataSource详解

我们来查看AbstractRoutingDataSource源码,来更好的理解多数据源配置。

首先查看该类的属性,根据名称我们能看出他们的作用。

private Map<Object, Object> targetDataSources;
private Object defaultTargetDataSource;
private boolean lenientFallback = true;
private DataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
private Map<Object, DataSource> resolvedDataSources;
private DataSource resolvedDefaultDataSource;

targetDataSources是目标数据源集合

defaultTargetDataSource是默认数据源

resolvedDataSources是解析后的数据源集合

resolvedDefaultDataSource是解析后的默认数据源

对数据源赋值的代码如下

public void setTargetDataSources(Map<Object, Object> targetDataSources) {
    this.targetDataSources = targetDataSources;
}

public void setDefaultTargetDataSource(Object defaultTargetDataSource) {
    this.defaultTargetDataSource = defaultTargetDataSource;
}
因为方法是set开头,我们便能把这两个方法配置在spring中,继续向下看。
public void afterPropertiesSet() {
    if (this.targetDataSources == null) {
        throw new IllegalArgumentException("Property 'targetDataSources' is required");
    } else {
        this.resolvedDataSources = new HashMap(this.targetDataSources.size());
        Iterator var1 = this.targetDataSources.entrySet().iterator();

        while(var1.hasNext()) {
            Entry<Object, Object> entry = (Entry)var1.next();
            Object lookupKey = this.resolveSpecifiedLookupKey(entry.getKey());
            DataSource dataSource = this.resolveSpecifiedDataSource(entry.getValue());
            this.resolvedDataSources.put(lookupKey, dataSource);
        }

        if (this.defaultTargetDataSource != null) {
            this.resolvedDefaultDataSource = this.resolveSpecifiedDataSource(this.defaultTargetDataSource);
        }

    }
}

这个afterPropertiesSet方法是遍历我们的targetDataSources数据源集合,并添加resolvedDataSources的map数据,map的key和value是根据resolveSpecifiedLookupKey方法和resolveSpecifiedDataSource方法得到。接着找到resolveSpecifiedLookupKey和resolveSpecifiedDataSource。

protected Object resolveSpecifiedLookupKey(Object lookupKey) {
    return lookupKey;
}

protected DataSource resolveSpecifiedDataSource(Object dataSource) throws IllegalArgumentException {
    if (dataSource instanceof DataSource) {
        return (DataSource)dataSource;
    } else if (dataSource instanceof String) {
        return this.dataSourceLookup.getDataSource((String)dataSource);
    } else {
        throw new IllegalArgumentException("Illegal data source value - only [javax.sql.DataSource] and String supported: " + dataSource);
    }
}

resolveSpecifiedLookupKey方法返回的实际就是targetDataSources的key,而resolveSpecifiedDataSource返回的是targetDataSources的value转成的DataSource。afterPropertiesSet方法的作用实际就是将原targetDataSources转成resolvedDataSources。

继续向下看,我们能看到数据库的连接方法。

public Connection getConnection() throws SQLException {
    return this.determineTargetDataSource().getConnection();
}

public Connection getConnection(String username, String password) throws SQLException {
    return this.determineTargetDataSource().getConnection(username, password);
}

我们接着去看determineTargeDataSource方法,估计这个方法是返回指定数据源的。

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;
    }
}

果然,这个方法是返回数据源的,我们来仔细读这个方法,从第3行开始”Object lookupKey = this.determineCurrentLookupKey();”,这个determineCurrentLookupKey返回了一个key,第四句是根据这个key去resolvedDataSources中拿到对应DataSource,接下来的代码是DataSource不存在便返回默认的数据源。determineCurrentLookupKey方法就是返回key的逻辑处理部分,联系spring中的配置,它返回的就是”cms”、”epg”中的一个。

<bean id="dynamicDataSource" class="com.lc.rout.DynamicDataSource">
    <property name="targetDataSources">
        <map>
            <entry key="cms" value-ref="cmsDataSource"/>
            <entry key="epg" value-ref="epgDataSource"/>
        </map>
    </property>
</bean>

我们在来看determineCurrentLookupKey方法。它是一个抽象方法,需要我们自己去写。

protected abstract Object determineCurrentLookupKey();

所以,我们需要实现这个抽象方法,返回一个指定数据源对应的key。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值