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);
    }
}
相关推荐
獨枭10 分钟前
使用 163 邮箱实现 Spring Boot 邮箱验证码登录
java·spring boot·后端
维基框架15 分钟前
Spring Boot 封装 MinIO 工具
java·spring boot·后端
秋野酱16 分钟前
基于javaweb的SpringBoot酒店管理系统设计与实现(源码+文档+部署讲解)
java·spring boot·后端
☞无能盖世♛逞何英雄☜29 分钟前
Flask框架搭建
后端·python·flask
Q_Q196328847537 分钟前
python的家教课程管理系统
开发语言·spring boot·python·django·flask·node.js·php
小白学大数据42 分钟前
基于Scrapy-Redis的分布式景点数据爬取与热力图生成
javascript·redis·分布式·scrapy
进击的雷神1 小时前
Perl语言深度考查:从文本处理到正则表达式的全面掌握
开发语言·后端·scala
进击的雷神1 小时前
Perl测试起步:从零到精通的完整指南
开发语言·后端·scala
Kookoos1 小时前
Redis + ABP vNext 构建分布式高可用缓存架构
redis·分布式·缓存·架构·c#·.net
豌豆花下猫2 小时前
Python 潮流周刊#102:微软裁员 Faster CPython 团队(摘要)
后端·python·ai