1. 程式人生 > >SpringBoot執行時動態新增資料來源

SpringBoot執行時動態新增資料來源

此方案適用於解決springboot專案執行時動態新增資料來源,非靜態切換多資料來源!!!

一、多資料來源應用場景:

1.配置檔案配置多資料來源,如預設資料來源:master,資料來源1:salve1...,執行時動態切換已配置的資料來源(master、salve1互相切換),無法在執行時動態新增配置檔案中未配置的資料來源。

2.配置一個預設資料來源,執行時動態新增新資料來源使用(本部落格適用於此場景)

二、解決方案:

Spring提供了AbstractRoutingDataSource用於動態路由資料來源,第一種場景繼承AbstractRoutingDataSource類並覆寫其protected abstract Object determineCurrentLookupKey()即可;
而第二種場景我們直接覆寫protected DataSource determineTargetDataSource方法即可。原理可看下AbstractRoutingDataSource對應原始碼,比較簡單,不做贅述。
直接上乾貨:

public class DynamicDataSource extends AbstractRoutingDataSource {

    private static final ThreadLocal<DataSource> dataSource = ThreadLocal.withInitial(() -> (DataSource) SpringUtils.getBean("defaultDataSource"));

    public static void setDataSource(DataSource dataSource) {
        DynamicDataSource.dataSource.set(dataSource);
    }

    public static DataSource getDataSource() {
        return DynamicDataSource.dataSource.get();
    }

    @Override
    protected Object determineCurrentLookupKey() {
        return null;
    }

    @Override
    protected DataSource determineTargetDataSource() {
        return getDataSource();
    }

    public static void clear() {
        DynamicDataSource.dataSource.remove();
    }
}

@Configuration
public class DataSourceConfig {

    @Bean
    @ConfigurationProperties("spring.datasource.druid")
    public DataSource defaultDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    public DynamicDataSource dataSource() {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        dynamicDataSource.setTargetDataSources(new HashMap<>());
        return dynamicDataSource;
    }
}

使用時直接呼叫DynamicDataSource.setDataSource(DataSource dataSource)方法即可,使用完後呼叫DynamicDataSource.clear()防止記憶體洩漏並重置預設資料來源