All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.luues.redis.single.aspect.RedisCacheAspect Maven / Gradle / Ivy

There is a newer version: 2.0.1.RELEASE
Show newest version
package com.luues.redis.single.aspect;

import cn.luues.tool.core.util.IdUtil;
import cn.luues.tool.core.util.StrUtil;
import cn.luues.tool.crypto.digest.DigestUtil;
import com.luues.exception.core.exception.RedisSynchronizedException;
import com.luues.exception.core.exception.VisitFrequentException;
import com.luues.exception.core.exception.VisitRefuseException;
import com.luues.redis.single.lock.RedisSynchronized;
import com.luues.redis.single.service.JedisTemplate;
import com.luues.redis.util.CommontUtil;
import lombok.SneakyThrows;
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.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import redis.clients.jedis.params.SetParams;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 通过aspect实现注解Rediscache
 * redis实现注解缓存
 */
@Aspect
@Component
@Slf4j(topic = "c.l.r.s.a.r")
public class RedisCacheAspect {
    @Autowired
    private JedisTemplate jedisTemplate;
    private Map methodMap = new HashMap<>();
    private Map redisSynchronizedMap = new HashMap<>();
    private Map paraNameArr = new HashMap<>();

    @Pointcut("@annotation(com.luues.redis.single.lock.RedisSynchronized)")
    public void synchroizedAspect() {
    }
    @Around("synchroizedAspect()")
    @SneakyThrows
    public Object synchroizedAspect(ProceedingJoinPoint joinPoint) {
        String name = joinPoint.getTarget().getClass().getName().concat("#").concat(joinPoint.getSignature().getName());
        if(null == methodMap.get(name))
            methodMap.put(name, ((MethodSignature)joinPoint.getSignature()).getMethod());
        Method objMethod = methodMap.get(name);
        if(null == redisSynchronizedMap.get(name))
            redisSynchronizedMap.put(name, objMethod.getAnnotation(RedisSynchronized.class));
        RedisSynchronized redisSynchronized = redisSynchronizedMap.get(name);
        String key = null, condition = null;
        Integer time = null, lockWaitTime = null, lockExpireTime = null;
        if (redisSynchronized != null) {
            key = redisSynchronized.key();
            time = redisSynchronized.time();
            lockWaitTime = redisSynchronized.lockWaitTime();
            lockExpireTime = redisSynchronized.lockExpireTime();
            condition = redisSynchronized.condition();
        }
        String an = "@RedisSynchronized";
        if (StrUtil.isBlank(key))
            throw new RedisSynchronizedException(an + " key() is not null!");
        if(lockExpireTime.intValue() <= 0)
            throw new RedisSynchronizedException(an + " lockExpireTime Must be greater than 0!");
        if(null == paraNameArr.get(name))
            paraNameArr.put(name, CommontUtil.getLocalVariableTableParameterNameDiscoverer().getParameterNames(objMethod));
        String[] paramNames = paraNameArr.get(name);
        Object[] objects = joinPoint.getArgs();
        StandardEvaluationContext context = new StandardEvaluationContext();
        for (int i = 0 ; i < paramNames.length ; i ++){
            context.setVariable(paramNames[i], objects[i]);
        }
        if(null != condition && condition.trim().length() > 0){
            if(!CommontUtil.getExpressionParser().parseExpression(condition).getValue(context, Boolean.class)){
                return joinPoint.proceed();
            }
        }
        key = CommontUtil.getExpressionParser().parseExpression(key).getValue(context, String.class);
        if (null == key)
            throw new RedisSynchronizedException(an + " key(" + key + ") not exist!");
        String redisKey = DigestUtil.md5Hex(objMethod.getClass().getName() + "->" + objMethod.getName() + "->" + key);
        String LockKey = "RedisSynchronized:Lock:" + redisKey;
        String uuid = IdUtil.randomUUID();
        boolean lock = false;
        if(lockWaitTime.intValue() == 0){
            lock = jedisTemplate.tryLock(LockKey, uuid, lockExpireTime);
        }else if(lockWaitTime.intValue() < 0){
            lock = jedisTemplate.lock(LockKey, uuid, lockExpireTime);
        }else{
            lock = jedisTemplate.lock(LockKey, uuid, lockWaitTime, lockExpireTime);
        }
        if(lock){
            try {
                if(time > 0 && null == jedisTemplate.set("RedisSynchronized:Time:" + redisKey, "SUCCESS", SetParams.setParams().nx().ex(time))){
                    throw new VisitFrequentException(StrUtil.isBlank(redisSynchronized.message()) ? "您的手速太快了,请稍后再试!" : redisSynchronized.message());
                }
                /*if(time > 0 && null == jedisTemplate.getJedis().set("RedisSynchroized:Time:" + redisKey, "SUCCESS", SetParams.setParams().nx().ex(time))){
                    throw new VisitFrequentException(StrUtil.isBlank(redissynchroized.message()) ? "您的手速太快了,请稍后再试!" : redissynchroized.message());
                }*/
                return joinPoint.proceed();
            } finally {
                jedisTemplate.unLock(LockKey, uuid);
            }
        }else{
            throw new VisitRefuseException(StrUtil.isBlank(redisSynchronized.message()) ? "当前已有请求正在执行,请稍后再试!" : redisSynchronized.message());
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy