动态数据源通过Spring的AbstractRoutingDataSource实现,JS通过请求头传递数据源标识,后端拦截并切换数据源,前端不直接控制。

JavaScript 本身无法直接在 Spring 框架中实现动态数据源,因为 Spring 是基于 Java 的后端框架,而 JavaScript 是前端语言。如果你指的是“如何通过 JS 前端调用接口”,从而触发 Spring 后端切换或配置动态数据源,那这个过程其实是前后端协作的结果。下面详细说明 在 Spring 中实现动态数据源的完整流程,并解释 JS 在其中的角色。
什么是动态数据源?
动态数据源是指应用程序在运行时根据业务需求,自动切换不同的数据库连接。常见场景包括:读写分离、多租户系统、按用户分配不同数据库等。
实现的核心是在 Spring 中使用 AbstractRoutingDataSource,通过重写其 determineCurrentLookupKey() 方法来决定当前使用哪个数据源。
Spring 实现动态数据源的步骤
1. 配置多个数据源
在 application.yml 或 application.properties 中定义多个数据库连接信息:
spring: datasource: master: url: jdbc:mysql://localhost:3306/master_db username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver slave: url: jdbc:mysql://localhost:3306/slave_db username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver
2. 创建数据源配置类
使用 Java Config 方式注入多个 DataSource Bean。
@Configurationpublic class DataSourceConfig { @Bean("master") @ConfigurationProperties("spring.datasource.master") public DataSource masterDataSource() { return DataSourceBuilder.create().build(); } @Bean("slave") @ConfigurationProperties("spring.datasource.slave") public DataSource slaveDataSource() { return DataSourceBuilder.create().build(); } @Bean public DynamicDataSource dynamicDataSource() { Map
3. 自定义 DynamicDataSource 类
继承 AbstractRoutingDataSource,实现动态路由逻辑。
public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSource(); }}
4. 创建数据源上下文持有者
使用 ThreadLocal 存储当前线程的数据源标识。
public class DataSourceContextHolder { private static final ThreadLocal contextHolder = new ThreadLocal(); public static void setDataSource(String key) { contextHolder.set(key); } public static String getDataSource() { return contextHolder.get(); } public static void clearDataSource() { contextHolder.remove(); }}
5. 使用注解 + AOP 实现数据源切换
定义一个自定义注解:
@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface DS { String value();}
通过 AOP 拦截注解,设置数据源:
@Aspect@Component@Order(-1) // 保证在事务之前执行public class DataSourceAspect { @Before("@annotation(ds)") public void before(JoinPoint point, DS ds) { String value = ds.value(); DataSourceContextHolder.setDataSource(value); } @After("@annotation(ds)") public void after(JoinPoint point, DS ds) { DataSourceContextHolder.clearDataSource(); }}
6. 在 Service 中使用
@Servicepublic class UserService { @DS("master") public void writeUser(User user) { // 写操作走主库 } @DS("slave") public List readAll() { // 读操作走从库 return userList; }}
JS 如何参与动态数据源的控制?
JavaScript(通常运行在浏览器)不能直接操作 Spring 的数据源切换,但它可以通过以下方式间接影响:
前端发送请求时携带数据源标识,例如在请求头中加入 X-DataSource: slave后端拦截请求,解析 header,并将数据源标记存入当前线程上下文中后续业务逻辑根据该标记自动切换数据源
示例:JS 发送请求指定数据源
fetch('/api/users', { method: 'GET', headers: { 'Content-Type': 'application/json', 'X-DataSource': 'slave' // 告诉后端使用从库 }}).then(response => response.json()).then(data => console.log(data));
后端通过 Interceptor 解析请求头:
@Componentpublic class DataSourceInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String ds = request.getHeader("X-DataSource"); if ("slave".equals(ds)) { DataSourceContextHolder.setDataSource("slave"); } else { DataSourceContextHolder.setDataSource("master"); } return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { DataSourceContextHolder.clearDataSource(); }}
总结与注意事项
动态数据源的关键在于 Spring 提供的扩展机制,而不是前端 JS 直接实现。JS 的作用是作为客户端,通过 API 请求传递意图(比如读/写、租户ID等),由后端据此进行数据源路由。
常见问题提醒:
确保 ThreadLocal 变量在线程结束时清除,避免内存泄漏AOP 切面优先级要高于事务管理,否则事务会锁定初始数据源多数据源不等于分布式事务,跨库写操作需引入 Seata 等解决方案
基本上就这些。理解清楚职责边界:JS 负责发起请求和传递上下文,Spring 才是真正实现动态数据源的核心。
以上就是JS怎样在Spring中实现动态数据源_JS在Spring中实现动态数据源的详细教程的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1536404.html
微信扫一扫
支付宝扫一扫