1、导入依赖
<!--redisson 是一个用于Java的Redis客户端,可以方便地在Java应用程序中使用Redis
AspectJ编织器,它可以用于实现AOP(面向切面编程)功能-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.13.6</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
</dependency>
2、redisson配置文件
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;
@Configuration
public class RedissonConfig {
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private int redisPort;
@Value("${spring.redis.database}")
private int redisDatabase;
/*redisson 不需要单独配置密码,指定好路径就行*/
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
SingleServerConfig serverConfig = config.useSingleServer();
serverConfig.setAddress("redis://" + redisHost + ":" + redisPort);
serverConfig.setDatabase(redisDatabase);
return Redisson.create(config);
}
}
此处翻车了,遇到了一个问题是在yml文件中配置了redis的路径、端口、密码、库,到配置redisson时顺理成章的把这些都拿过来配置,导致报错说这个bean注册不成功,连接不上redis,!!!原因是:redisson连接时不需要密码,去掉就创建成功了(具体为什么我也不知道,可能是依赖关系)
3、编辑注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributedLock {
String key();
long leaseTime() default 30; // 默认锁定时间,单位:秒
long waitTime() default 10; // 默认等待时间,单位:秒
}
4、编辑增强逻辑
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Aspect
@Component
@RequiredArgsConstructor
public class DistributedLockAspect {
private final RedissonClient redissonClient;
@Around("@annotation(distributedLock)")
public Object around(ProceedingJoinPoint joinPoint, DistributedLock distributedLock) throws Throwable {
String key = distributedLock.key();
long leaseTime = distributedLock.leaseTime();
long waitTime = distributedLock.waitTime();
RLock lock = redissonClient.getLock(key);
boolean acquired = false;
try {
acquired = lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
if (acquired) {
return joinPoint.proceed();
} else {
throw new RuntimeException("Could not acquire lock on key: " + key);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Lock acquisition interrupted", e);
} finally {
if (acquired) {
lock.unlock();
}
}
}
}
5、启动类上增加注解
@EnableAspectJAutoProxy //启用了AspectJ自动代理
6、使用
在方法上使用注解就可以了
@DistributedLock(key = "materialCollection:lock:#datas[0].accountId", waitTime = 100, leaseTime = 10)