SpringBoot如何在運行時動態(tài)添加數據源
此方案適用于解決springboot項目運行時動態(tài)添加數據源,非靜態(tài)切換多數據源?。?!
一、多數據源應用場景:
1.配置文件配置多數據源,如默認數據源:master,數據源1:salve1...,運行時動態(tài)切換已配置的數據源(master、salve1互相切換),無法在運行時動態(tài)添加配置文件中未配置的數據源。
2.配置一個默認數據源,運行時動態(tài)添加新數據源使用(本博客適用于此場景)
二、解決方案:
Spring提供了AbstractRoutingDataSource用于動態(tài)路由數據源,第一種場景繼承AbstractRoutingDataSource類并覆寫其protected abstract Object determineCurrentLookupKey()即可;
而第二種場景我們直接覆寫protected DataSource determineTargetDataSource方法即可。原理可看下AbstractRoutingDataSource對應源碼,比較簡單,不做贅述。
直接上干貨:
import com.fizz.utils.spring.SpringUtils;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import javax.sql.DataSource;
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();
}
}
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import java.util.HashMap;
@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()防止內存泄漏并重置默認數據源。
附上詳細使用方法:
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setUrl("jdbc:mysql://localhost:3306/sys?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC&useAffectedRows=true");
druidDataSource.setUsername("root");
druidDataSource.setPassword("root");
DynamicDataSource.setDataSource(druidDataSource);
此時數據源已切換到druidDataSource ,調用自己的業(yè)務方法即可。
使用完后調用DynamicDataSource.clear();重置為默認數據源。
附上工具類SpringUtils :
import lombok.Getter;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public final class SpringUtils implements ApplicationContextAware {
@Getter
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtils.applicationContext == null) {
SpringUtils.applicationContext = applicationContext;
}
}
public static <T> T getBean(Class<T> clazz) {
return SpringUtils.applicationContext.getBean(clazz);
}
public static Object getBean(String name) {
return SpringUtils.applicationContext.getBean(name);
}
public static String getProperty(String key) {
return SpringUtils.applicationContext.getEnvironment().getProperty(key);
}
}
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Springboot+Mybatis中typeAliasesPackage正則掃描實現方式
這篇文章主要介紹了Springboot+Mybatis中typeAliasesPackage正則掃描實現方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
詳解Spring Boot配置文件application.properties
在本文中我們給大家整理了關于Spring Boot 的配置文件 application.properties的相關知識點內容,需要的朋友們參考學習下。2019-06-06
springboot整合webservice使用簡單案例總結
WebService是一個SOA(面向服務的編程)的架構,它是不依賴于語言,平臺等,可以實現不同的語言間的相互調用,下面這篇文章主要給大家介紹了關于springboot整合webservice使用的相關資料,需要的朋友可以參考下2024-07-07
Hystrix?Turbine聚合監(jiān)控的實現詳解
微服務架構下,?個微服務往往部署多個實例,如果每次只能查看單個實例的監(jiān)控,就需要經常切換很不?便,在這樣的場景下,我們可以使??Hystrix?Turbine?進?聚合監(jiān)控,它可以把相關微服務的監(jiān)控數據聚合在?起,便于查看2022-09-09
Spring?Boot?中使用@KafkaListener并發(fā)批量接收消息的完整代碼
kakfa是我們在項目開發(fā)中經常使用的消息中間件。由于它的寫性能非常高,因此,經常會碰到讀取Kafka消息隊列時擁堵的情況,這篇文章主要介紹了Spring?Boot?中使用@KafkaListener并發(fā)批量接收消息,需要的朋友可以參考下2023-02-02

