lock4j是基于Spring AOP 的声明式和编程式分布式锁,支持RedisTemplate、Redisson、Zookeeper

文档


目录
  • 快速开始
  • Lock4j注解源码
  • 参考文章


快速开始

依赖

<!--若使用redisTemplate作为分布式锁底层,则需要引入-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>lock4j-redis-template-spring-boot-starter</artifactId>
    <version>2.2.4</version>
</dependency>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

本例使用redisTemplate,还支持redisson、zookeeper

配置

spring:
  redis:
    host: 127.0.0.1
  • 1.
  • 2.
  • 3.

使用示例

指定时间内不释放锁(限流)

@RestController
public class IndexController {

    // 用户在5秒内只能访问1次
    @GetMapping("/lockMethod")
    @Lock4j(keys = {"#userId"}, acquireTimeout = 0, expire = 5000, autoRelease = false)
    public String lockMethod(@Param("userId") String userId) {
        return userId;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

不同用户访问同一个接口,每个用户都分别被限流,每5秒才能访问一次

http://localhost:8080/lockMethod?userId=tom

http://localhost:8080/lockMethod?userId=jack
  • 1.
  • 2.
  • 3.

当加锁的时候,redis中会写入类似如下的数据

// key value
lock4j:com.example.demo.controller.IndexControllerlockMethod#tom 7578d8ae49e74864865a417e56b5bb1b
lock4j:com.example.demo.controller.IndexControllerlockMethod#jack aff5db5959954da7b12b3c99d9582869
  • 1.
  • 2.
  • 3.

完整代码:https://github.com/mouday/spring-boot-demo/tree/master/SpringBoot-Lock4j

Lock4j注解源码

/**
 * 分布式锁注解
 *
 * @author zengzhihong TaoYu
 */
@Target(value = {ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Lock4j {

    /**
     * 用于多个方法锁同一把锁 可以理解为锁资源名称 为空则会使用 包名+类名+方法名
     *
     * @return 名称
     */
    String name() default "";

    /**
     * @return lock 执行器
     */
    Class<? extends LockExecutor> executor() default LockExecutor.class;

    /**
     * support SPEL expresion 锁的key = name + keys
     *
     * @return KEY
     */
    String[] keys() default "";

    /**
     * @return 过期时间 单位:毫秒
     * <pre>
     *     过期时间一定是要长于业务的执行时间. 未设置则为默认时间30秒 默认值:{@link Lock4jProperties#expire}
     * </pre>
     */
    long expire() default -1;

    /**
     * @return 获取锁超时时间 单位:毫秒
     * <pre>
     *     结合业务,建议该时间不宜设置过长,特别在并发高的情况下. 未设置则为默认时间3秒 默认值:{@link Lock4jProperties#acquireTimeout}
     * </pre>
     */
    long acquireTimeout() default -1;

    /**
     * 业务方法执行完后(方法内抛异常也算执行完)自动释放锁,如果为false,锁将不会自动释放直至到达过期时间才释放 {@link com.baomidou.lock.annotation.Lock4j#expire()}
     *
     * @return 是否自动释放锁
     */
    boolean autoRelease() default true;

}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.

参考文章

1、 一个强大的分布式锁框架——Lock4j