前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring多数据源配置系列(二)——AbstractRoutingDataSource详解

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

作者头像
逝兮诚
发布2019-10-30 18:01:25
2.2K0
发布2019-10-30 18:01:25
举报
文章被收录于专栏:代码人生代码人生代码人生

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/luo4105/article/details/77743161

我们来查看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。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-08-31 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档