底层实现原理
本文说明 com.molandev.core.lock 的架构与 Memory / Redisson 两种实现。
整体架构
应用层:@GlobalLock / @Idempotent / LockUtils
↓
切面层:LockAspect / IdempotentAspect
↓
核心层:LockFactory
├── MemoryLockFactory → MemoryLock
└── RedissonLockFactory → RedissonLock自动配置见 LockAutoConfiguration:
- 若配置了
molandev.lock.type(memory|redisson)→ 使用该值 - 否则按
molandev.mode:microservice→redisson,其余 →memory type=redisson但容器中无RedissonClient→ 启动失败(避免误用本地锁)
Memory 实现
基于 JDK ReentrantLock,进程内互斥,适合 standalone 与单测。
要点:
- 可重入、无外部依赖
- 不跨 JVM;多实例部署不可用 Memory
- 工厂侧可对长时间未使用的锁做清理,避免 Map 膨胀
Redisson 实现
委托 Redisson RLock,适合微服务多实例。
要点:
- 可重入(Redis Hash)
- 看门狗可在未指定 leaseTime 时自动续期(以 Redisson 行为为准)
- 依赖 classpath 中的 Redisson,并需完成 Redis 连接配置
yaml
molandev:
mode: microservice
# lock.type 可省略,微服务默认 redisson
spring:
data:
redis:
host: localhost
port: 6379注解与工具类
@GlobalLock:AOP 解析 SpEL key,再调用LockUtils.runInLock@Idempotent:用锁 + 过期时间做短时幂等LockUtils:编程式入口,统一走当前LockFactory
选型建议
| 实现 | 场景 |
|---|---|
| Memory | 本地单体、单测 |
| Redisson | 微服务、多实例定时任务 / 幂等 |
不要在微服务多实例下显式配置 lock.type=memory,否则锁只在单机生效。
常见问题
Q: 为什么去掉 RedisTemplate 锁?
A: 与 Redisson 能力重叠且更弱(无看门狗等)。现只保留 Memory + Redisson。
Q: 未配置 lock.type 会怎样?
A: 跟随 molandev.mode;未配 mode 时默认 Memory。
Q: 微服务启动报找不到 RedissonClient?
A: 引入 Redisson 并配置 Redis,或显式 molandev.lock.type=memory(仅单实例可接受)。