redis通用缓存设计(2)

上篇文章实现了redis的通用缓存,但是用起来不是很灵活,用within表达式,使得service的每个业务都用到了缓存。

如果想要指定哪些方法上用缓存,哪些不用该怎么设计?

例如:在UserServiceImpl实现类中有findAll和findOne两个方法,我想要在查询所有findAll这一部分添加缓存,而findOne不加入缓存。

这就要用到自定义注解来设计,有关自定义注解可以参考:https://www.cnblogs.com/acm-bingzi/p/javaAnnotation.html

设计思路:

1.首先设计一个RedisCache自定义注解这样一个类。

/*
自定义注解,value = ElementType.METHOD表示该注解用在方法上
 */
@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RedisCache {

    public String value();
}

2.这样的自定义注解类用在哪个方法上,就在该方法上写  @RedisCache("value")

3.在切面类中判断,业务层方法上有自定义注解RedisCache,然后执行缓存操作,否则就什么也不做

@Around("execution(* com.lkl.service.*ServiceImpl.find*(..))")
    public Object around(ProceedingJoinPoint pjp){
        //判断当前切入的方法上是否存在rediscache这个注解
        MethodSignature signature1 = (MethodSignature) pjp.getSignature();

        Method method = signature1.getMethod();//先获取方法对象
        //判断有没有RedisCache这个注解
        boolean isHaveAnnotation = method.isAnnotationPresent(RedisCache.class);
        if (isHaveAnnotation){   //切入的方法上有这个注解,执行切面操作
            //获取key
            String key = getKey(pjp);
            //获取jedis对象,以默认端口号6379连接
            Jedis jedis = new Jedis("192.168.1.*",6379);
            Object result = null;
            //判断Redis中是否存在这个key
            if(jedis.exists(key)){//如果存在取出数据返回
                System.out.println("the data is exist in redis,direct return ");
                String json = jedis.get(key);
                //把这个签名,转换为反射包中的MethodSignature
                MethodSignature signature = signature1;
                System.out.println(signature.getReturnType());
                result = JSONObject.parseObject(json,signature.getReturnType());

            }else{ //如果不存在,放行Dao方法执行存入Redis中
                System.out.println("the data is not exist in redis,query the DB");
                try {
                    result = pjp.proceed();//放行
                    //放入redis中,以json形式存入
                    jedis.set(key,JSONObject.toJSONString(result));
                } catch (Throwable throwable) {
                    throwable.printStackTrace();
                }
            }
            return result;

        }else {    //没有这个注解什么也不做,直接放行
            Object proceed = null;
            try {
                proceed = pjp.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            return proceed;
        }

    }
原文地址:https://www.cnblogs.com/lkldeblog/p/11276681.html