shardingsphere 的 hint 强制路由不依赖注解原生支持,但可通过自定义@shardinghint注解+aop+hintmanager实现声明式路由;需注意优先级最高、线程安全及事务顺序等限制。

ShardingSphere 的 Hint 强制路由不依赖注解原生支持,官方未提供 @ShardingHint 这类内置注解。但你可以通过自定义注解 + AOP + HintManager 实现「声明式 Hint 路由」,让业务代码更简洁、可读性更强。
一、定义自定义 Hint 注解
创建一个运行时保留的注解,用于标记需要强制分库/分表的方法:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ShardingHint {
String database() default ""; // 指定库值,如 "ds_1"
String table() default ""; // 指定表后缀,如 "01"
boolean clearAfterInvocation() default true; // 是否自动清理 Hint
}
二、编写 AOP 切面拦截并注入 Hint
使用 Spring AOP 在方法执行前设置 Hint,并在结束后按需清理:
@Aspect
@Component
public class ShardingHintAspect {
@Around("@annotation(hint)")
public Object doShardingHint(ProceedingJoinPoint joinPoint, ShardingHint hint) throws Throwable {
try {
HintManager hintManager = HintManager.getInstance();
hintManager.clear();
if (StringUtils.hasText(hint.database())) {
hintManager.setDatabaseShardingValue(hint.database());
}
if (StringUtils.hasText(hint.table())) {
hintManager.setTableShardingValue(hint.table());
}
return joinPoint.proceed();
} finally {
if (hint.clearAfterInvocation()) {
HintManager.clear();
}
}
}
}
注意:必须确保切面在 ShardingSphere 数据源代理之前生效,且目标方法调用的是被 ShardingSphere 代理的 Mapper 或 JdbcTemplate。
三、在 DAO 层方法上使用注解
直接在 Service 或 Mapper 接口方法上标注,无需手动操作 HintManager:
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@ShardingHint(database = "ds_2", table = "03")
@Override
public Order selectById(Long id) {
return orderMapper.selectById(id); // 将强制路由到 ds_2 + t_order_03
}
}
该方式适用于确定性路由场景(如根据租户 ID 固定查某库某表),不适用于动态计算分片键的场景(此时仍建议显式用 HintManager)。
四、注意事项与限制
- Hint 路由优先级最高,会覆盖分片规则和 SQL 解析结果,慎用于写操作,避免数据错写
- 多线程下
HintManager是基于 ThreadLocal 的,AOP 切面必须保证在同一线程内完成整个逻辑 - 若方法内部开启新线程(如
CompletableFuture),Hint 不会自动传递,需手动透传或改用setDatabaseShardingValue配合ThreadLocal手动管理 - Spring 事务中使用 Hint 时,需确保 AOP 切面顺序在
@Transactional之后(可通过@Order控制),否则事务可能已开启但 Hint 未生效
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











