美文网首页
SpringBoot多数据源配置

SpringBoot多数据源配置

作者: 白驹过隙_忽然而已 | 来源:发表于2022-02-25 14:14 被阅读0次

1. 关键类

AbstractRoutingDataSource

public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {
    //多数据源Map lockup key -> DataSource
    private Map<Object, Object> targetDataSources;
    //默认数据源
    private Object defaultTargetDataSource;

    private Map<Object, DataSource> resolvedDataSources;

    private DataSource resolvedDefaultDataSource;
    @Override
    public void afterPropertiesSet() {
        if (this.targetDataSources == null) {
            throw new IllegalArgumentException("Property 'targetDataSources' is required");
        }
        this.resolvedDataSources = new HashMap<Object, DataSource>(this.targetDataSources.size());
        for (Map.Entry<Object, Object> entry : this.targetDataSources.entrySet()) {
            Object lookupKey = resolveSpecifiedLookupKey(entry.getKey());
            DataSource dataSource = resolveSpecifiedDataSource(entry.getValue());
            this.resolvedDataSources.put(lookupKey, dataSource);
        }
        if (this.defaultTargetDataSource != null) {
            this.resolvedDefaultDataSource = resolveSpecifiedDataSource(this.defaultTargetDataSource);
        }
    }

项目启动后,将targetDataSources复制到resolvedDataSources中

//返回当前需要的数据源,由子类实现的方法来提供lockupkey
    protected DataSource determineTargetDataSource() {
        Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
        Object lookupKey = determineCurrentLookupKey();
        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 + "]");
        }
        return dataSource;
    }

    //子类实现获取lockupkey的逻辑
    protected abstract Object determineCurrentLookupKey();
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
  //在线程T h r
    @Override
    protected Object determineCurrentLookupKey() {
        LOGGER.info("current datasource is : {}", DynamicDataSourceContextHolder.getDataSourceKey());
        return DynamicDataSourceContextHolder.getDataSourceKey();
    }
}

利用ThreadLocal来存储线程当前的lockupkey

public class DynamicDataSourceContextHolder {

    private static ThreadLocal<Object> CONTEXT_HOLDER = ThreadLocal.withInitial(() -> "lookupkey");

相关文章

网友评论

      本文标题:SpringBoot多数据源配置

      本文链接:https://www.haomeiwen.com/subject/ipyxrrtx.html