需求就是:一个服务接口不允许同时去访问,由于接口很多,用注解的方式动态给服务接口添加分分布式锁
引入redission的jar
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.11.0</version>
</dependency>
引入spring aop的jar
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
redissionClient配置
@Slf4j
@Configuration
public class RedssionConfig {
@Bean
public RedissonClient redissonClient(){
RedissonClient redissonClient=null;
//获取config的实例
Config config = new Config();
//设置请求的URL地址
String url="redis://10.83.128.11:6379";
//设置config
config.useSingleServer().setAddress(url).setPassword("redis");
//通过Redisson来创建一个客户端对象
try{
redissonClient= Redisson.create(config);
log.info("创建RedissonClient成功");
return redissonClient;
}catch (Exception err){
log.info("创建RedissonClient失败:"+err.fillInStackTrace());
return null;
}
}
}
利用 redissionClient添加加锁和解锁操作
@Slf4j
@Component
public class DistributeRedisLock {
@Autowired
private RedissonClient redissonClient;
private long MAX_LOCK_WAIT_TIME = 30;// 秒
public boolean lock(String lockName){
try {
if(null==redissonClient){ //如果对象没有注入进来那么说明是有问题的
log.info("注入redissonClient对象失败----");
return false;
}
//获取这个锁
RLock lock = redissonClient.getLock(lockName);
//锁住了
lock.lock(MAX_LOCK_WAIT_TIME, TimeUnit.SECONDS);
log.info("加锁成功----");
return true;
} catch (Exception e) {
log.info("不可预期的异常造成了加锁失败----");
return false;
}
}
public boolean unlock(String lockName){
try {
if(null==redissonClient){ //说明没法释放出问题了....
log.info("释放锁失败----"+lockName);
}
//获取到这个锁对象
RLock lock = redissonClient.getLock(lockName);
if(null!=lock){
lock.unlock();
log.info("释放锁成功----");
return true;
}
return false;
} catch (Exception e) {
log.info("释放锁失败了----");
return false;
}
}
}
定义动态添加分布式锁的注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RedissionLock {
String value() default "";
}
定义注解切面,在添加注解的方法调用之前获取分布式锁,调用之后解除分布式锁
@Aspect
@Component
@Slf4j
public class RedissionLockAspect {
@Autowired
private DistributeRedisLock distributeRedisLock;
@Pointcut("@annotation(com.bigdata.stu.azkaban.redission.RedissionLock)")
public void redissionLockPointCut() {
}
@Before("redissionLockPointCut()")
public void before(JoinPoint joinPoint) throws Exception {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
RedissionLock redissionLock = method.getAnnotation(RedissionLock.class);
if (redissionLock != null) {
String lockName = redissionLock.value();
distributeRedisLock.lock(lockName);
}
}
@After("redissionLockPointCut()")
public void after(JoinPoint joinPoint) throws Exception {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
RedissionLock redissionLock = method.getAnnotation(RedissionLock.class);
if (redissionLock != null) {
String lockName = redissionLock.value();
distributeRedisLock.unlock(lockName);
}
}
}
测试类:
@Slf4j
@RestController
public class TestRedission {
@Autowired
private DistributeRedisLock distributeRedisLock;
@RedissionLock("test1")
@RequestMapping("/testRedission1")
public String test1(String name) {
try {
Thread.sleep(40000);
}catch (Exception e){
e.printStackTrace();
}
return "success";
}
@RedissionLock("test2")
@RequestMapping("/testRedission2")
public String test2(String name) {
try {
Thread.sleep(400);
}catch (Exception e){
e.printStackTrace();
}
return "success";
}
}