Update RedisLockAspect.java

cyj
pbvfus8to 8 months ago
parent 3b04b4f8aa
commit fc835290dc

@ -27,48 +27,82 @@ import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* Redis
* Spring AOPRedis
* `@RedisLock`线
*
* @author lgh
*/
@Aspect
// 使用 @Aspect 注解声明该类是一个切面类,用于定义切点和增强逻辑(如前置通知、后置通知、环绕通知等)
@Component
// 使用 @Component 注解将该类注册为Spring容器中的一个组件方便进行依赖注入等操作
public class RedisLockAspect {
@Autowired
private RedissonClient redissonClient;
@Autowired
// 通过依赖注入获取RedissonClient对象用于与Redis进行交互操作Redis锁相关的功能
private RedissonClient redissonClient;
// 定义Redis锁的键名前缀用于在Redis中区分不同的锁方便管理和识别
private static final String REDISSON_LOCK_PREFIX = "redisson_lock:";
private static final String REDISSON_LOCK_PREFIX = "redisson_lock:";
/**
* `@RedisLock`
* Redis线
*
* @param joinPoint
* @param redisLock `@RedisLock`
* @return `@RedisLock`
* @throws Throwable
*/
@Around("@annotation(redisLock)")
// 使用 @Around 注解定义环绕通知,该通知会在目标方法执行前后进行额外的逻辑处理,这里就是围绕着被标注`@RedisLock`注解的方法进行加锁和解锁操作
public Object around(ProceedingJoinPoint joinPoint, RedisLock redisLock) throws Throwable {
// 获取`@RedisLock`注解中定义的用于生成锁键的SPEL表达式SPEL表达式可以根据方法参数等动态生成锁键
String spel = redisLock.key();
// 获取`@RedisLock`注解中定义的锁名称,用于更直观地标识锁的用途等信息
String lockName = redisLock.lockName();
@Around("@annotation(redisLock)")
public Object around(ProceedingJoinPoint joinPoint, RedisLock redisLock) throws Throwable {
String spel = redisLock.key();
String lockName = redisLock.lockName();
// 根据连接点、锁名称以及SPEL表达式生成最终的Redis锁的键名并通过RedissonClient获取对应的Redis锁对象
RLock rLock = redissonClient.getLock(getRedisKey(joinPoint, lockName, spel));
RLock rLock = redissonClient.getLock(getRedisKey(joinPoint,lockName,spel));
// 使用获取到的Redis锁对象进行加锁操作设置锁的过期时间和时间单位按照`@RedisLock`注解中定义的配置来进行
rLock.lock(redisLock.expire(), redisLock.timeUnit());
rLock.lock(redisLock.expire(),redisLock.timeUnit());
Object result = null;
try {
// 执行被标注`@RedisLock`注解的目标方法,即让原本的业务逻辑正常执行
result = joinPoint.proceed();
Object result = null;
try {
//执行方法
result = joinPoint.proceed();
} finally {
// 无论目标方法执行是否成功,最终都要释放锁,确保锁资源能够被正确释放,避免死锁等问题
rLock.unlock();
}
return result;
}
} finally {
rLock.unlock();
}
return result;
}
/**
* SPELRedis
* SPELSPELRedis
*
* @param joinPoint SPEL
* @param lockName Redis
* @param spel SPEL
* @return Redis"redisson_lock:锁名称:具体解析后的表达式内容"Redis
*/
private String getRedisKey(ProceedingJoinPoint joinPoint, String lockName, String spel) {
// 获取连接点对应的方法签名信息,用于后续获取目标方法对象
Signature signature = joinPoint.getSignature();
// 将方法签名信息转换为方法签名的具体实现类对象,方便获取目标方法的详细信息
MethodSignature methodSignature = (MethodSignature) signature;
// 获取目标方法对象后续可用于解析SPEL表达式等操作
Method targetMethod = methodSignature.getMethod();
// 获取目标对象即被代理的实际业务对象同样可用于解析SPEL表达式等操作
Object target = joinPoint.getTarget();
// 获取目标方法的参数数组这些参数在解析SPEL表达式时可能会作为变量参与计算
Object[] arguments = joinPoint.getArgs();
/**
* spel
* @param joinPoint
* @return redisKey
*/
private String getRedisKey(ProceedingJoinPoint joinPoint,String lockName,String spel) {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method targetMethod = methodSignature.getMethod();
Object target = joinPoint.getTarget();
Object[] arguments = joinPoint.getArgs();
return REDISSON_LOCK_PREFIX + lockName + StrUtil.COLON + SpelUtil.parse(target,spel, targetMethod, arguments);
}
}
// 通过工具类方法解析SPEL表达式结合锁名称等信息生成最终的Redis锁键字符串并添加前缀形成完整的用于在Redis中标识锁的键名
return REDISSON_LOCK_PREFIX + lockName + StrUtil.COLON + SpelUtil.parse(target, spel, targetMethod, arguments);
}
}
Loading…
Cancel
Save