SpringBoot动态数据源配置:让项目更灵活的实战技巧

在程序员的世界里,技术的成长往往伴随着一次次挑战与突破。今天,我将分享一个我在实际开发中遇到的问题,并通过SpringBoot实现动态数据源配置的解决方案,这是一次让我对灵活性和扩展性有了更深理解的经历。


背景故事


最近,我在负责一个需要对接多个数据库的项目时,遇到了一个问题:如何在运行时动态添加新的数据源?传统的静态配置方式显然无法满足需求,而手动修改代码再重启服务又显得过于笨重。于是,我开始探索一种更加优雅的方式——动态数据源配置。


什么是动态数据源?


简单来说,动态数据源就是在程序运行过程中,可以根据业务需求随时切换或新增数据源,而无需重新启动应用。这种技术特别适用于多租户系统、分布式架构等场景,能够显著提升系统的灵活性和可维护性。


实现步骤详解


为了帮助大家更好地理解这个过程,我将分步介绍如何在SpringBoot项目中实现动态数据源配置:


  • 1. 引入依赖

首先,在项目的pom.xml文件中引入必要的依赖项。这里主要用到的是Spring Boot Starter JDBC以及Druid连接池:


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>

  • 2. 创建数据源管理类

接下来,我们需要创建一个用于管理数据源的类。这个类会维护一个Map结构,用来存储所有的数据源实例:


@Component
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
private Map<Object, Object> dataSourceMap = new HashMap<>();

public void addDataSource(String key, DataSource dataSource) {
dataSourceMap.put(key, dataSource);
afterPropertiesSet(); // 通知父类重新初始化目标数据源
}

@Override
protected Object determineCurrentLookupKey() {
return CONTEXT_HOLDER.get();
}

public static void setDataSource(String key) {
CONTEXT_HOLDER.set(key);
}

public static void clearDataSource() {
CONTEXT_HOLDER.remove();
}
}

  • 3. 配置数据源

在Spring Boot的配置文件中,我们可以预先定义一些默认的数据源:


spring.datasource.primary.url=jdbc:mysql://localhost:3306/primary_db
spring.datasource.primary.username=root
spring.datasource.primary.password=123456

spring.datasource.secondary.url=jdbc:mysql://localhost:3306/secondary_db
spring.datasource.secondary.username=root
spring.datasource.secondary.password=123456

然后通过Java代码加载这些配置并注册到DynamicDataSource中:


@Configuration
public class DataSourceConfig {
@Autowired
private DynamicDataSource dynamicDataSource;

@Bean
public DataSource primaryDataSource(@Value("${spring.datasource.primary.url}") String url,
@Value("${spring.datasource.primary.username}") String username,
@Value("${spring.datasource.primary.password}") String password) {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dynamicDataSource.addDataSource("primary", dataSource);
return dataSource;
}

@Bean
public DataSource secondaryDataSource(@Value("${spring.datasource.secondary.url}") String url,
@Value("${spring.datasource.secondary.username}") String username,
@Value("${spring.datasource.secondary.password}") String password) {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dynamicDataSource.addDataSource("secondary", dataSource);
return dataSource;
}
}

  • 4. 动态切换数据源

最后,在实际使用时,我们可以通过调用DynamicDataSource的setDataSource方法来切换当前使用的数据源:


DynamicDataSource.setDataSource("primary");
try {
// 执行针对primary数据源的操作
} finally {
DynamicDataSource.clearDataSource();
}

总结


通过这次实践,我深刻体会到动态数据源配置的强大之处。它不仅提高了系统的灵活性,还为未来的扩展提供了更多可能性。希望我的经验能对你有所帮助!如果你也有类似的需求或者更好的实现方式,欢迎留言交流。

点赞(0)

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部