上篇文章实现了redis的通用缓存,可是用起来不是很灵活,用within表达式,使得service的每一个业务都用到了缓存。html
若是想要指定哪些方法上用缓存,哪些不用该怎么设计?java
例如:在UserServiceImpl实现类中有findAll和findOne两个方法,我想要在查询全部findAll这一部分添加缓存,而findOne不加入缓存。redis
这就要用到自定义注解来设计,有关自定义注解能够参考:https://www.cnblogs.com/acm-bingzi/p/javaAnnotation.htmljson
设计思路:缓存
1.首先设计一个RedisCache自定义注解这样一个类。spa
/* 自定义注解,value = ElementType.METHOD表示该注解用在方法上 */ @Target(value = ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RedisCache { public String value(); }
2.这样的自定义注解类用在哪一个方法上,就在该方法上写 @RedisCache("value")设计
3.在切面类中判断,业务层方法上有自定义注解RedisCache,而后执行缓存操做,不然就什么也不作code
@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; } }