1

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();
    }
}

Zeran
32 声望4 粉丝

学而不思则罔,思而不学则殆。