redis自定义注解实现缓存

1.自定义注解属性名称

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface RedisCacheable {
    enum KeyMode {
        DEFAULT,    //只有加了@CacheKey的参数,才加入key后缀中
        BASIC,      //只有基本类型参数,才加入key后缀中,如:String,Integer,Long,Short,Boolean
        ALL,        //所有参数都加入key后缀
        USER,        //所有参数都加入key后缀,并且加入当前访问用户ID
        BEAN,       //bean的属性加入KEY后缀
        MAP        //Map的属性加入KEY后缀
    }

    String key() default "";     //缓存key

    KeyMode keyMode() default KeyMode.USER;       //key的后缀模式

    int expire() default 10;      //缓存多少秒,默认10秒

2.自定义切面

@Aspect
@Component
public class RedisCacheableAspect {
    Logger logger = LoggerFactory.getLogger(RedisCacheableAspect.class);

    @Around("@annotation(cache)")
    public Object cached(final ProceedingJoinPoint pjp, RedisCacheable cache) throws Throwable {
        String key = null;
        Object value = null;
        try {
            MethodSignature signature = (MethodSignature)pjp.getSignature();
            Class returnType = signature.getReturnType();
            key = getCacheKey(pjp, cache);
            // 从缓存获取数据
            value = RedisCacheService.get(key, returnType);
            if (value != null) {
                logger.info("**********RedisCacheableAspect返回Redis公共缓存数据:" + value);
                return value;
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        // 跳过缓存,到后端查询数据
        value = pjp.proceed();
        if (value == null) {
            return value;
        }

        try {
            if (cache.expire() <= 0) {
                // 如果没有设置过期时间,则无限期缓存
                RedisCacheService.set(key, value);
            } else {
                // 否则设置缓存时间
                RedisCacheService.set(key, value, cache.expire());
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return value;
    }

    /**
     * 获取缓存的key值
     *
     * @param joinPoint
     * @param cache
     * @return
     */
    private String getCacheKey(ProceedingJoinPoint joinPoint, RedisCacheable cache) {
        // 切点的类完全限定名称
        String className = joinPoint.getSignature().toString();

        StringBuilder buf = new StringBuilder("CACH-ANNO-APP-");
        buf.append(className);
        String keyStr = cache.key();

        if (cache.keyMode() == RedisCacheable.KeyMode.BEAN) {
            if (keyStr.length() > 0) {
                buf.append(".").append(keyStr);
            }

        }

        Object[] args = joinPoint.getArgs();
        if (cache.keyMode() == RedisCacheable.KeyMode.DEFAULT) {
            Annotation[][] pas = ((MethodSignature)joinPoint.getSignature()).getMethod().getParameterAnnotations();
            for (int i = 0; i < pas.length; i++) {
                Object target = args[0];
                Field field = ReflectionUtils.findField(target.getClass(), keyStr);
                ReflectionUtils.makeAccessible(field);
                Object value = ReflectionUtils.getField(field, target);
                buf.append("#").append(value);
            }
        } else if (cache.keyMode() == RedisCacheable.KeyMode.MAP) {
            if (keyStr.length() > 0) {
                Map target = (Map)args[0];
                buf.append("#").append(target.get(keyStr));
            }
        } else if (cache.keyMode() == RedisCacheable.KeyMode.ALL) {
            buf.append(Arrays.toString(joinPoint.getArgs()));
        } else if (cache.keyMode() == RedisCacheable.KeyMode.USER) {
            buf.append(Arrays.toString(joinPoint.getArgs()));
            buf.append("#").append(CurrentUserUtil.getUsername());
        }
        return buf.toString();
    }
}

3.方式使用自定义注解实现缓存

@RedisCacheable(keyMode = RedisCacheable.KeyMode.ALL, expire = 60 * 60 * 24)
 public void testmethod() {
      
 }

4.redis的后台监控

进入redis客户端,使用MONITOR命令可以监控redis的set和get过程。

 

posted @ 2022-11-01 16:57  老王的日常  阅读(405)  评论(0)    收藏  举报