缓存redis使用@Cacheable注解

1. 建立Cacheable注解类

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Cacheable {
    String value() default "";

    String key() default "";

    int expire() default 3600;
}

2. Aspect拦截并缓存结果,也可以直接用SpringBoot   RedisTemplate

@Component
public class RedisClient {

    private static final Logger logger = LoggerFactory.getLogger(RedisClient.class);

    @Value("${spring.redis.host}")
    public String host;

    @Value("${spring.redis.port}")
    public int port;

    @Value("${spring.redis.password}")
    public String password;

    public JedisPool jedisPool;
    
    public RedisClient(){

    }

    public RedisClient(JedisPool pool) {
        this.jedisPool = pool;
    }


    @Bean
    public RedisClient getDefaultClient(){
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxIdle(100);
        config.setMaxTotal(1000);
        this.jedisPool  = new JedisPool(config, host, port, 6000, password);
        RedisClient client = new RedisClient(this.jedisPool);
        return client;
    }

    public Long setnx(String key, String value) {
        Jedis client = jedisPool.getResource();
        try {
            Long result = client.setnx(key, value);
           return result;
        } finally {
            client.close();
        }
    }
    public String getSet(String key, String newValue) {
        Jedis client = jedisPool.getResource();
        try {
            return client.getSet(key, newValue);
        } finally {
            client.close();// 向连接池“归还”资源
        }
    }
    public boolean set(String key, String value) {
        Jedis client = jedisPool.getResource();
        String isSuccess ;
        try {
            isSuccess = client.set(key, value);
            if ("OK".equals(isSuccess)) {
                return true;
            } else {
                return false;
            }
        } finally {
            client.close();// 向连接池“归还”资源
        }
    }
    /**
     * 根据key来获取对应的value
     */
    public Object getKey(String key) {
        Jedis client = jedisPool.getResource();
        Object o = null;
        try {
            o = client.get(key);
        } finally {
            client.close();// 向连接池“归还”资源
        }
        return o;
    }
    /**
     *
     * @param key
     * @param seconds
     * @return
     */
    public Long expire(String key,Integer seconds){
        Jedis client = jedisPool.getResource();
        Long success = 1l;
        try{
            success = client.expire(key, seconds);
        }finally{
            client.close();
        }
        return success;
    }

    public boolean delKey(String key) {
        Jedis client = jedisPool.getResource();
        try {
            client.del(key);
            logger.info("del key:{}, result:{}",key, client.get(key));
            return true;
        } finally {
            client.close();
        }
    }
    /**set Object*/
    public String setSerialize(String key,Object object) {
        Jedis client = jedisPool.getResource();
        logger.info("setSerialize key:{},value:{}",key, new Gson().toJson(object));
        logger.info("SerializeUtil.serialize(object): " + SerializeUtil.serialize(object));
        try {
            return client.set(key.getBytes(), SerializeUtil.serialize(object));
        } finally {
            client.close();
        }
    }


    /**get Object*/
    public Object getSerialize(String key) {
        Jedis client = jedisPool.getResource();
        byte[] value;
        try {
            value = client.get(key.getBytes());
        } finally {
            client.close();
        }
        if(value == null){
            return value;
        }
        logger.info("getSerialize key:{},value:{}",key,new Gson().toJson(SerializeUtil. unserialize(value)));
        return SerializeUtil. unserialize(value);
    }

    /**delete a key**/
    public boolean delSerialize(String key) {
        Jedis client = jedisPool.getResource();
        try {
            return client.del(key.getBytes())>0;
        } finally {
            client.close();
        }
    }
}

@Slf4j
@Aspect
@Component
public class CacheLockAspect {


    @Autowired
    private RedisClient redisClient;

   /* @Around("@annotation(annotation.CacheLock)")
    public Object cacheable(ProceedingJoinPoint pjp) throws Throwable {
        Method method = this.getMethod(pjp);
        CacheLock cacheLock = method.getAnnotation(CacheLock.class);
        if (cacheLock == null) {
            log.info("no CacheLock annotation");
            return pjp.proceed();
        }
        String key = getCacheKey(cacheLock.key(), cacheLock.value(), method, pjp.getArgs());

        boolean result = lock.lock(key, cacheLock.expireTime());
        if (!result) {// 锁失败,证明被其他线程持有
            log.info("get lock fail";
            return null;
        }
        try {
            // 执行方法
            return pjp.proceed();
        } finally {
            lock.unlock(key);// 释放锁
        }
    }*/
    @Around("@annotation(Cacheable对应包名)")
    public Object getCacheable(ProceedingJoinPoint pjp) throws RuntimeException {
        Object obj = null;
        Method method = this.getMethod(pjp);
        Cacheable cacheable = method.getAnnotation(Cacheable.class);
        int expire = cacheable.expire();
        String key = this.getCacheKey(cacheable.key(), cacheable.value(), method, pjp.getArgs());
        try {
            obj = redisClient.getSerialize(key);
        } catch (Exception var12) {
            log.warn("redis connection exception : {}", var12);
        }

        if(obj != null) {
            log.debug("before method:{} cacheable get cache key:{} data:{}", new Object[]{method.getName(), key, obj});
            return obj;
        } else {
            try {
                obj = pjp.proceed();
            } catch (Throwable var11) {
                log.warn("redis cacheable aspect proceed exception:{}", var11);
                throw new RuntimeException(var11);
            }
            if(obj != null) {
                try {
                    redisClient.setSerialize(key,obj);
                    redisClient.expire(key,expire);
                } catch (Exception var10) {
                    log.warn("redis connection exception : {}", var10);
                }
                log.debug("after method:{} cacheable set cache key:{} data:{}", new Object[]{method.getName(), key, obj});
            }
            return obj;
        }
    }
    @SuppressWarnings("rawtypes")
    private Method getMethod(ProceedingJoinPoint pjp) {
        Object[] args = pjp.getArgs();
        Class[] argTypes = new Class[pjp.getArgs().length];

        for (int method = 0; method < args.length; ++method) {
            argTypes[method] = args[method].getClass();
        }

        Method var8 = null;

        try {
            var8 = pjp.getTarget().getClass().getMethod(pjp.getSignature().getName(), argTypes);
            return var8;
        } catch (NoSuchMethodException var6) {
            log.warn("redis cacheable aspect no such method exception:{}", var6);
            throw new RuntimeException(var6);
        } catch (SecurityException var7) {
            log.warn("redis cacheable aspect method security exception:{}", var7);
            throw new RuntimeException(var7);
        }
    }

    private String getCacheKey(String key, String value, Method method, Object[] args) {
        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
        String[] paraNameArr = u.getParameterNames(method);
        SpelExpressionParser parser = new SpelExpressionParser();
        StandardEvaluationContext context = new StandardEvaluationContext();

        for (int i = 0; i < paraNameArr.length; ++i) {
            context.setVariable(paraNameArr[i], args[i]);
        }

        return value + "_" + parser.parseExpression(key).getValue(context, String.class);
    }
}

3.在方法明上添加

@Cacheable(value="cacheUserInfo", key="#key", expire = 3600)
public Object cacheUserInfo(String key) {}



你可能感兴趣的:(缓存redis使用@Cacheable注解)