AOP+Redis實現redis緩存

1.定義註解

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AspectCache {
    String key();

    /**
     * 定義時間
     *
     * @return 返回int
     */
    int seconds() default 0;

    CACHE_TYPE cacheType() default CACHE_TYPE.FIND;

    enum CACHE_TYPE {
        FIND,
        UPDATE
    }
}

2.切面類

@Aspect
@Component
@Slf4j
public class CacheAspectConfig {

    private final RedisUtil redisUtil;

    @Autowired
    public CacheAspectConfig(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }

    @Around("@annotation(aspectCache)")
    public Object doAround(ProceedingJoinPoint joinPoint, AspectCache aspectCache) throws Throwable {
        return aroundMethod(joinPoint, aspectCache);
    }

    /**
     * @param joinPoint   鏈接點
     * @param aspectCache 註解
     * @return 返回object
     * @throws Throwable 異常
     */
    public Object aroundMethod(ProceedingJoinPoint joinPoint, AspectCache aspectCache) throws Throwable {
        String redisKey = aspectCache.key() + "::" + Arrays.toString(joinPoint.getArgs());
        Object result = null;
        MethodSignature methodType = (MethodSignature) joinPoint.getSignature();
        Class<?> returnType = methodType.getReturnType();

        // 計時開始
        log.info("-------------執行{}方法開始-----------", joinPoint.getSignature().getName());
        Stopwatch started = Stopwatch.createStarted();
        switch (aspectCache.cacheType()) {
            case FIND:
                // 查詢緩存
                result = findMethod(joinPoint, redisKey, returnType, aspectCache);
                break;
            case UPDATE:
                // 更新緩存
                result = updateMethod(joinPoint, redisKey);
                break;
            default:
                result = findMethod(joinPoint, redisKey, returnType, aspectCache);
                break;
        }
        log.info("-------------執行:{}方法開始,所耗時:{}ms-----------", joinPoint.getSignature().getName(), started.stop());
        return result;
    }

    /**
     * @param joinPoint   鏈接點
     * @param key         key
     * @param targetClass 類型
     * @param aspectCache 註解對象
     * @return object 返回數據
     * @throws Throwable 拋出異常
     */
    private Object findMethod(ProceedingJoinPoint joinPoint, String key, Class<?> targetClass, AspectCache aspectCache) throws Throwable {
        Object result = null;
        if (redisUtil.hasKey(key)) {
            log.info("-----------緩存中有數據,從緩存中取------------");
            String json = (String) redisUtil.get(key);
            result = JSON.toJavaObject(JSONObject.parseObject(json), targetClass);
        } else {
            log.info("-----------------查詢數據庫------------------");
            result = joinPoint.proceed();
            if (aspectCache.seconds() > ServiceConstants.INTEGER_ZERO) {
                redisUtil.set(key, JSONObject.toJSONString(result), aspectCache.seconds());
            } else {
                redisUtil.set(key, JSONObject.toJSONString(result));
            }
        }
        return result;
    }

    /**
     * 更新緩存
     *
     * @param joinPoint 鏈接點
     * @param key       key
     * @return object
     * @throws Throwable 異常
     */
    private Object updateMethod(ProceedingJoinPoint joinPoint, String key) throws Throwable {
        log.info("--------------------刪除緩存------------------");
        redisUtil.del(key);
        return joinPoint.proceed();
    }
}
相關文章
相關標籤/搜索