Spring Boot 整合 Lock4j + Redisson 实现分布式锁实战

本文基于 Spring Boot 2.7.x + MyBatis Plus 3.5.9,演示如何通过 Lock4j 与 Redisson 实现高可靠的分布式锁方案,解决高并发场景下的资源竞争问题。


一、依赖配置关键点

1.1 Maven 依赖(pom.xml)

xml 复制代码
			 <dependency>
                <groupId>org.redisson</groupId>
                <artifactId>redisson-spring-boot-starter</artifactId>
                <version>3.41.0</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-actuator</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.redisson</groupId>
                        <!-- 使用 redisson-spring-data-27 替代,解决 Tuple NoClassDefFoundError 报错 -->
                        <artifactId>redisson-spring-data-34</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.redisson</groupId>
                <artifactId>redisson-spring-data-27</artifactId>
                <version>3.41.0</version>
            </dependency>
            
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>lock4j-redisson-spring-boot-starter</artifactId>
                <version>2.2.7</version>
                <exclusions>
                    <exclusion>
                        <artifactId>redisson-spring-boot-starter</artifactId>
                        <groupId>org.redisson</groupId>
                    </exclusion>
                </exclusions>
            </dependency>

1.2 依赖关系说明

依赖 作用 版本控制策略
lock4j-redisson-* Lock4j 分布式锁核心实现 继承自项目 BOM 统一管理
redisson-spring-boot-starter Redisson 客户端 Starter 显式指定版本保证兼容性
redisson-spring-data-27 Spring Data 2.7 适配模块 与 Spring Boot 2.7.x 版本严格对应

二、为什么需要显式排除依赖?

2.1 解决版本冲突问题

  • Lock4j 默认依赖的 Redisson 版本可能较低 ,通过 <exclusions> 排除后使用项目统一管理的 Redisson 3.41.0
  • Spring Data 版本适配 :Spring Boot 2.7.x 对应 Spring Data 2.7,需使用 redisson-spring-data-27 模块

2.2 避免不必要依赖

  • 排除 spring-boot-starter-actuator:若项目未使用监控端点,减少无用依赖
  • 排除 redisson-spring-data-34:防止与 Spring Data 2.7 产生兼容性问题

三、配置验证(application.yml)

yaml 复制代码
spring:
  # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
  redis:
    host: 127.0.0.1 # 地址
    port: 6379 # 端口
    database: 0 # 数据库索引
    password: 123456 # 密码,建议生产环境开启
# Lock4j 配置项
lock4j:
  acquire-timeout: 3000 # 获取锁等待超时时间,默认为 3000 毫秒
  expire: 30000 # # 默认锁过期时间(毫秒),默认为 30 毫秒
  store-type: redis # 使用 Redis 实现

四、锁失败策略配置(核心防御机制)

4.1 DefaultLockFailureStrategy 源码解析

java 复制代码
/**
 * 自定义获取锁失败策略,抛出 {@link ServiceException} 异常
 */
@Slf4j
public class DefaultLockFailureStrategy implements LockFailureStrategy {

    @Override
    public void onLockFailure(String key, Method method, Object[] arguments) {
        log.debug("[onLockFailure][线程:{} 获取锁失败,key:{} 获取失败:{} ]", Thread.currentThread().getName(), key, arguments);
        throw new ServiceException(GlobalErrorCodeConstants.LOCKED);
    }
}

关键设计点:

  • 日志分级 :使用 debug 级别避免生产环境日志膨胀
  • 异常标准化 :通过 GlobalErrorCodeConstants.LOCKED 统一返回 "请求过于频繁" 提示
  • 上下文保留:记录线程、锁Key、方法参数等关键信息便于问题排查

五、自动装配机制(集成关键)

5.1 DyhLock4jConfiguration 配置类

java 复制代码
@AutoConfiguration(before = LockAutoConfiguration.class)
@ConditionalOnClass(name = "com.baomidou.lock.annotation.Lock4j")
public class DyhLock4jConfiguration {

    @Bean
    public DefaultLockFailureStrategy lockFailureStrategy() {
        return new DefaultLockFailureStrategy();
    }

}

注解解析:

注解 作用
@AutoConfiguration Spring Boot 3.0+ 新特性,替代传统 @Configuration 更精准控制加载顺序
before = LockAutoConfiguration.class 确保在 Lock4j 默认配置前加载,避免 Bean 冲突
@ConditionalOnClass 存在 Lock4j 注解时才生效,实现条件化装配

5.2 配置类加载流程说明

流程分解

text 复制代码
1. Spring Boot 启动
   │
   └─▶ 扫描所有 AutoConfiguration 类
        │
        ├─▶ 检测是否存在 Lock4j 注解(@ConditionalOnClass)
        │    │
        │    ├─ 存在 → 加载 DyhLock4jConfiguration
        │    │       │
        │    │       └─▶ 注册 DefaultLockFailureStrategy Bean
        │    │              │
        │    │              └─▶ 初始化 Lock4j 组件
        │    │
        │    └─ 不存在 → 跳过分布式锁配置
        │
        └─▶ 继续其他自动配置

关键节点说明

步骤 说明 对应代码片段
条件检测 @ConditionalOnClass 注解检查 classpath 是否存在 com.baomidou.lock.annotation.Lock4j 类 @ConditionalOnClass(name = "com.baomidou.lock.annotation.Lock4j")
配置顺序控制 @AutoConfiguration(before = LockAutoConfiguration.class) 确保自定义配置在 Lock4j 默认配置前加载 @AutoConfiguration(before = LockAutoConfiguration.class)
Bean 注册 通过 @Bean 注解将失败策略注入 Spring 容器 @Bean public DefaultLockFailureStrategy lockFailureStrategy()

六、实战开发示例

java 复制代码
@Service
@RequiredArgsConstructor
public class OrderService {
    private final OrderMapper orderMapper;

    // 分布式锁注解
    @Lock4j(
            name = "order_create_#{#orderDTO.userId}", // 动态锁名(SpEL)
            expire = 10000,      // 锁自动释放时间(毫秒)
            acquireTimeout = 2000 // 获取锁等待时间
    )
    @Transactional
    public void createOrder(OrderDTO orderDTO) {
        // 1. 幂等校验
        Order existOrder = orderMapper.selectByUserId(orderDTO.getUserId());
        if (existOrder != null) {
            throw new ServiceException("订单已存在");
        }

        // 2. 业务操作(如扣减库存)
        reduceStock(orderDTO.getProductId());

        // 3. 创建订单
        Order order = new Order().setUserId(orderDTO.getUserId());
        orderMapper.insert(order);
    }
}
相关推荐
渣哥12 分钟前
从代理到切面:Spring AOP 的本质与应用场景解析
javascript·后端·面试
文心快码BaiduComate29 分钟前
文心快码3.5S实测插件开发,Architect模式令人惊艳
前端·后端·架构
5pace34 分钟前
【JavaWeb|第二篇】SpringBoot篇
java·spring boot·后端
HenryLin35 分钟前
Kronos核心概念解析
后端
oak隔壁找我35 分钟前
Spring AOP源码深度解析
java·后端
货拉拉技术37 分钟前
大规模 Kafka 消费集群调度方案
后端
oak隔壁找我37 分钟前
MyBatis Plus 源码深度解析
java·后端
oak隔壁找我38 分钟前
Druid 数据库连接池源码详细解析
java·数据库·后端
剽悍一小兔38 分钟前
Nginx 基本使用配置大全
后端
LCG元38 分钟前
性能排查必看!当Linux服务器CPU/内存飙高,如何快速定位并"干掉"罪魁祸首进程?
linux·后端