RedisCacheGetAspect.java 1.97 KB
Newer Older
张辰's avatar
张辰 committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
package com.tanpu.community.cache;

import com.alibaba.fastjson.JSON;
import com.tanpu.common.redis.RedisHelper;
import com.tanpu.common.redis.RedisKeyHelper;
import com.tanpu.community.util.SpringUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.time.Duration;

@Aspect
@Component
public class RedisCacheGetAspect {

    private static RedisKeyHelper keyHelper = new RedisKeyHelper("community2_cache:");

    @Around(value = "@annotation(com.tanpu.community.cache.CacheGet)")
    public Object methodAround(ProceedingJoinPoint jp) throws Throwable {

        MethodSignature ms = (MethodSignature) jp.getSignature();
        CacheGet anno = ms.getMethod().getAnnotation(CacheGet.class);
        String prefix = anno.prefix();
        int expireSeconds = anno.expireSeconds();

        if (expireSeconds < 0) {
            throw new RuntimeException("expire second cannot be negative.");
        }

        RedisHelper redisHelper = SpringUtils.getBean(RedisHelper.class);
        String key = keyHelper.buildKeyCustom(":", prefix, StringUtils.joinWith(":", jp.getArgs()));
        String value = redisHelper.get(key);
        // todo 考虑缓存穿透的问题.
        if (StringUtils.isNotBlank(value)) {
            return JSON.parseObject(value, ms.getReturnType());
        }

        try {
            Object ret = jp.proceed();

            String putValue = ret == null ? "null" : JSON.toJSONString(ret);
            if (expireSeconds == 0) {
                redisHelper.set(key, putValue);
            } else {
                redisHelper.set(key, putValue, Duration.ofSeconds(expireSeconds));
            }

            return ret;
        } catch (Throwable t) {
            // todo wrap this throwable
            throw new RuntimeException(t);
        }
    }
}