java多数据源路由通过@datasourceroute接口定义路由契约,结合aop动态设置threadlocal上下文,由dynamicroutingdatasource依据上下文返回对应数据源,业务层仅需注解声明,零侵入实现数据源动态切换。

Java 中通过接口实现多数据源路由契约,核心是定义一个统一的、可被动态解析的数据源选择协议,让业务代码不感知具体数据源,而由框架或中间层根据契约决定使用哪个数据源。
定义数据源路由标识接口
创建一个轻量级接口,作为“路由契约”的声明点,不包含方法,仅用于标记和类型识别:
- 用 @Target({ElementType.METHOD, ElementType.TYPE}) 支持注解在方法或类上
- 用 @Retention(RetentionPolicy.RUNTIME) 确保运行时可读取
- 定义一个 value() String 属性,表示逻辑数据源名(如 "master"、"slave01"、"tenant_a")
示例:
@Target({METHOD, TYPE})@Retention(RUNTIME)
public @interface DataSourceRoute {
String value();
}
结合 AOP 实现运行时路由注入
利用 Spring AOP 拦截标注了 @DataSourceRoute 的方法,在执行前将目标数据源名写入线程上下文(如 ThreadLocal
当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。
- 编写切面,提取注解中的 value(),存入自定义的 DataSourceContextHolder.set("slave01")
- 确保切面优先级高于事务管理器(避免事务已开启后才切换数据源)
- 方法结束后清空 ThreadLocal,防止线程复用导致脏数据
对接 Spring 的 AbstractRoutingDataSource
继承 AbstractRoutingDataSource,重写 determineCurrentLookupKey() 方法,从上下文中读取路由标识:
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.get(); // 返回如 "slave01"
}
}
并在配置中将所有真实数据源(如 HikariCP 实例)注册进 setTargetDataSources(Map,key 即为路由标识字符串。
业务层按契约使用,零侵入
开发者只需在 Service 方法上声明路由意图,无需手动获取 Connection 或 DataSource:
@Servicepublic class OrderService {
@DataSourceRoute("slave01")
public List
@DataSourceRoute("master")
@Transactional
public void createOrder(Order order) { ... }
}
这样就完成了“接口定义契约 → AOP 解析契约 → 路由数据源执行”的闭环,扩展新数据源只需新增配置 + 新增路由值,不改业务代码。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










