SpringBoot多数据源配置

1. 关键类

AbstractRoutingDataSource

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

    private Map resolvedDataSources;

    private DataSource resolvedDefaultDataSource;
    @Override
    public void afterPropertiesSet() {
        if (this.targetDataSources == null) {
            throw new IllegalArgumentException("Property 'targetDataSources' is required");
        }
        this.resolvedDataSources = new HashMap(this.targetDataSources.size());
        for (Map.Entry 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 CONTEXT_HOLDER = ThreadLocal.withInitial(() -> "lookupkey");
 

                            
                        
                    
                    
                    

你可能感兴趣的:(SpringBoot多数据源配置)