我是靠谱客的博主 贪玩树叶,最近开发中收集的这篇文章主要介绍Springboot2.X整合redisson实现分布式锁,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.添加依赖:


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2.添加配置类:

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* redisson bean管理
*/
@Configuration
public class RedissonConfig {
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private String redisPost;
@Value("${spring.redis.password}")
private String redisPassword;
/**
* Redisson客户端注册
* 单机模式
*/
@Bean(destroyMethod = "shutdown")
public RedissonClient createRedissonClient(){
//读取配置,官方参考地址:https://github.com/redisson/redisson
Config config = new Config();
SingleServerConfig singleServerConfig = config.useSingleServer();
singleServerConfig.setAddress("redis://" + redisHost + ":" + redisPost);
singleServerConfig.setPassword(redisPassword);
singleServerConfig.setTimeout(3000);
//放置redis第二个桶
singleServerConfig.setDatabase(1);
return Redisson.create(config);
}
@Bean
public RedissonDistributedLockImpl redissonLocker(RedissonClient redissonClient) {
RedissonDistributedLockImpl locker = new RedissonDistributedLockImpl(redissonClient);
return locker;
}
}

3.添加自定义注解类:

3.1annotation:

import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RedissonLock {
}

3.2aspect:

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* 基于redis的redisson客户端实现分布式锁
*
*/
@Aspect
@Component
@Slf4j
public class RedissonLockAspect {
public static final int WAIT_GET_LOCK_TIME = 3000;
public static final int WAIT_RELEASE_LOCK_TIME = 5000;
@Autowired
private IRedissonDistributedLock iRedissonDistributedLock;
@Value("${spring.application.name}")
private String serverName;
/**
* 切点
*/
@Pointcut("@annotation(com.xx.xx.xx.redis.redisson.aspect.annotation.RedissonLock)")
public void redissonLockPoint() {
}
/**
*
* @param point 代表当前正在运行的方法
* @return Object 结果
* @throws Throwable e
*/
@Around("redissonLockPoint()")
public Object checkLock(ProceedingJoinPoint point) throws Throwable {
//当前线程名称
String threadName = Thread.currentThread().getName();
//获取当前类名
Object className = point.getTarget().getClass().getName();
//拦截的方法名称
String methodName = point.getSignature().getName();
log.info("当前线程:{}------进入分布式锁AOP------", threadName);
//生成分布式锁:服务名+类名+方法名
String lockRedisKey = serverName + ":" + className + ":" + methodName;
log.info("当前线程:{},分布式锁的key:{}", threadName, lockRedisKey);
//获取锁3000等到获取锁的时间,leaseTime 获取锁后持有时间时间,单位 MILLISECONDS:毫秒
if (iRedissonDistributedLock.tryLock(lockRedisKey, WAIT_GET_LOCK_TIME, WAIT_RELEASE_LOCK_TIME, TimeUnit.MILLISECONDS)) {
try {
log.info("当前线程:{},获取锁成功", threadName);
return point.proceed();
} catch (Throwable throwable) {
throw new Exception(throwable);
} finally {
if (iRedissonDistributedLock.isLocked(lockRedisKey)) {
log.info("当前线程:{}, key:{},对应的锁被线程持有", threadName, lockRedisKey);
if (iRedissonDistributedLock.isHeldByCurrentThread(lockRedisKey)) {
log.info("当前线程:{},key:{},保持锁定", threadName, lockRedisKey);
iRedissonDistributedLock.unlock(lockRedisKey);
log.info("当前线程:{},key:{},释放锁", threadName, lockRedisKey);
}
}
}
} else {
log.info("当前线程:{},获取锁失败", threadName);
//这里return可以根据自己业务改造,我这里是返回“系统繁忙,请稍后再试!”
return Result.error(AppErrorCodeEnum.SYSTEM_BUSY.getMessage());
}
}
}

4.添加redisson客户端类:

4.1接口:

import java.util.concurrent.TimeUnit;
public interface IRedissonDistributedLock {
/**
* 加锁
* @param lockKey key
*/
void lock(String lockKey);
/**
* 加锁锁,设置有效期
*
* @param lockKey key
* @param timeout 有效时间,默认时间单位在实现类传入
*/
void lock(String lockKey, int timeout);
/**
* 加锁,设置有效期并指定时间单位
* @param lockKey key
* @param timeout 有效时间
* @param unit
时间单位
*/
void lock(String lockKey, int timeout, TimeUnit unit);
/**
* 释放锁
*
* @param lockKey key
*/
void unlock(String lockKey);
/**
* 尝试获取锁,获取到则持有该锁返回true,未获取到立即返回false
* @param lockKey 锁
* @return true-获取锁成功 false-获取锁失败
*/
boolean tryLock(String lockKey);
/**
* 尝试获取锁,获取到则持有该锁leaseTime时间.
* 若未获取到,在waitTime时间内一直尝试获取,超过waitTime还未获取到则返回false
* @param lockKey
key
* @param waitTime
尝试获取时间
* @param leaseTime 锁持有时间
* @param unit
时间单位
* @return true-获取锁成功 false-获取锁失败
* @throws InterruptedException e
*/
boolean tryLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit)
throws InterruptedException;
/**
* 锁是否被任意一个线程锁持有
* @param lockKey 锁
* @return true-被锁 false-未被锁
*/
boolean isLocked(String lockKey);
/**
* isHeldByCurrentThread()的作用是查询当前线程是否保持此锁定
* @param lockKey 锁
* @return true or false
*/
boolean isHeldByCurrentThread(String lockKey);
}

4.2实现:

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import java.util.concurrent.TimeUnit;
/**
* redisson实现分布式锁接口
*/
public class RedissonDistributedLockImpl implements IRedissonDistributedLock {
private final RedissonClient redissonClient;
/**
* 构造方法 赋予本类的redisClient以实例
* @param redissonClient client
*/
public
RedissonDistributedLockImpl(RedissonClient redissonClient) {
this.redissonClient = redissonClient;
}
@Override
public void lock(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock();
}
@Override
public void lock(String lockKey, int leaseTime) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock(leaseTime, TimeUnit.MILLISECONDS);
}
@Override
public void lock(String lockKey, int timeout, TimeUnit unit) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock(timeout, unit);
}
@Override
public void unlock(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
lock.unlock();
}
@Override
public boolean tryLock(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
return lock.tryLock();
}
@Override
public boolean tryLock(String lockKey, long waitTime, long leaseTime,
TimeUnit unit) throws InterruptedException {
RLock lock = redissonClient.getLock(lockKey);
return lock.tryLock(waitTime, leaseTime, unit);
}
@Override
public boolean isLocked(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
return lock.isLocked();
}
@Override
public boolean isHeldByCurrentThread(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
return lock.isHeldByCurrentThread();
}
}

最后

以上就是贪玩树叶为你收集整理的Springboot2.X整合redisson实现分布式锁的全部内容,希望文章能够帮你解决Springboot2.X整合redisson实现分布式锁所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(65)

评论列表共有 0 条评论

立即
投稿
返回
顶部