SpringBoot中配置多數(shù)據(jù)源的方法詳解
開始配置多數(shù)據(jù)源
首先我們需要先移除自動配置數(shù)據(jù)源,SpringBoot 的默認行為
DataSourceAutoConfiguration 是 SpringBoot 提供的自動配置類
@SpringBootApplication(scanBasePackages = "com", exclude = {DataSourceAutoConfiguration.class})
下面首先讀取了默認數(shù)據(jù)源的信息,通過 getProperties() 封裝成一個 Map 對象
定義了一個名為 dynamicDataSource 的 bean 是數(shù)據(jù)源路由器,它繼承了 AbstractRoutingDataSource 類,我們可以根據(jù)規(guī)則選擇要使用的數(shù)據(jù)源。
dataSource 方法接受一個 Map,并返回一個數(shù)據(jù)源,于是我們就創(chuàng)建了一個數(shù)據(jù)源
這段代碼通過設(shè)置,配置了一個支持動態(tài)切換的數(shù)據(jù)源,默認使用 master,用于運行時動態(tài)切換數(shù)據(jù)源。
@Configuration @Slf4j public class DataSourceConfigurer { @Value("${spring.datasource.druid.master.url}") private String url; @Value("${spring.datasource.druid.master.username}") private String username; @Value("${spring.datasource.druid.master.password}") private String password; @Value("${spring.datasource.driverClassName}") private String driverClassName; /** * 獲取數(shù)據(jù)源配置信息 * * @return 數(shù)據(jù)源配置信息 */ private Map<String, Object> getProperties() { Map<String, Object> map = new HashMap<>(); map.put("driverClassName", driverClassName); map.put("url", url); map.put("username", username); map.put("password", password); return map; } /** * 配置動態(tài)數(shù)據(jù)源 * * @return 動態(tài)數(shù)據(jù)源 */ @Bean("dynamicDataSource") public DynamicRoutingDataSource dynamicDataSource() { DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource(); // 創(chuàng)建數(shù)據(jù)源 DataSource dataSource = dynamicRoutingDataSource.dataSource(getProperties()); // 設(shè)置數(shù)據(jù)源映射 Map<Object, Object> dataSourceMap = new HashMap<>(1); dataSourceMap.put("default_db", dataSource); dynamicRoutingDataSource.setTargetDataSources(dataSourceMap); // 設(shè)置默認數(shù)據(jù)源 dynamicRoutingDataSource.setDefaultTargetDataSource(dataSource); return dynamicRoutingDataSource; } }
具體切換多數(shù)據(jù)源的邏輯 DynamicRoutingDataSource
多數(shù)據(jù)源切換的實現(xiàn)的關(guān)鍵是 AbstractRoutingDataSource
我們這里創(chuàng)建了一個 targetTargetDataSources 是一個 Map 存儲數(shù)據(jù)源的數(shù)據(jù),key 數(shù)據(jù)源的標識,value 是具體的數(shù)據(jù)源。通過 setTargetDataSources 可以設(shè)置數(shù)據(jù)源,在運行時,通過該方法切換。
通過 addDataSource 添加數(shù)據(jù)源,并通過 setTargetDataSources 使數(shù)據(jù)源生效。
existDataSource 是判斷數(shù)據(jù)源是否存在
dataSource 這個是重要的方法,它是為數(shù)據(jù)源在druid 連接池中創(chuàng)建了資源,配置了數(shù)據(jù)源。
/** * 動態(tài)數(shù)據(jù)源 */ @Slf4j public class DynamicRoutingDataSource extends AbstractRoutingDataSource { private static Map<Object, Object> targetTargetDataSources = new ConcurrentHashMap<>(); @Override protected Object determineCurrentLookupKey() { // 每次連接數(shù)據(jù)庫,都會去設(shè)置數(shù)據(jù)源 return DynamicDataSourceContextHolder.getDataSourceKey(); } // 設(shè)置targetDataSources并記錄數(shù)據(jù)源(這里可以記錄每個數(shù)據(jù)源的最近使用時間,可以做刪除不經(jīng)常使用的數(shù)據(jù)源) @Override public void setTargetDataSources(Map<Object, Object> targetDataSources) { super.setTargetDataSources(targetDataSources); super.afterPropertiesSet(); targetTargetDataSources = targetDataSources; } // 添加數(shù)據(jù)源 public void addDataSource(String tenant, Map<String, Object> dataSourceProperties) { targetTargetDataSources.put(tenant, dataSource(dataSourceProperties)); super.setTargetDataSources(targetTargetDataSources); afterPropertiesSet(); } // 判斷是否存在數(shù)據(jù)源,存在直接取 public boolean existDataSource(String tenant) { return targetTargetDataSources.containsKey(tenant); } // 組裝數(shù)據(jù)源 public DataSource dataSource(Map<String, Object> dataSourceProperties) { DataSource dataSource; try { dataSource = DruidDataSourceFactory.createDataSource(dataSourceProperties); } catch (Exception e) { log.error("dataSource: {}", e.getMessage()); throw new RuntimeException(); } return dataSource; } }
到此這篇關(guān)于SpringBoot中配置多數(shù)據(jù)源的方法詳解的文章就介紹到這了,更多相關(guān)SpringBoot配置多數(shù)據(jù)源內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot2.x 整合 thumbnailator 圖片處理的示例代碼
這篇文章主要介紹了SpringBoot2.x 之整合 thumbnailator 圖片處理,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10java的各種集合為什么不安全(List、Set、Map)以及代替方案
這篇文章主要介紹了java的各種集合為什么不安全(List、Set、Map)以及代替方案,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10springboot運行到dokcer中 dockerfile的場景分析
這篇文章主要介紹了springboot運行到dokcer中 dockerfile,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-03-03