上篇文章實現了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; } }