您好,登錄后才能下訂單哦!
導(dǎo)入redis的jar包
<!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.0.4.RELEASE</version> </dependency>
編寫自定義緩存注解
/** * @Description: redis緩存注解 編寫在需要緩存的類上 **/ @Documented @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface RedisCache { }
編寫切面類
package com.ys.edu.aop; import com.ys.edu.utils.ResultUtils; import org.apache.log4j.Logger; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.stereotype.Service; import org.aspectj.lang.reflect.MethodSignature; import javax.annotation.Resource; import java.util.Arrays; import java.util.Set; import java.util.concurrent.TimeUnit; /** * @ClassName RedisAOP * @description: redis 切面緩存 **/ @Aspect @Service public class RedisAOP { private static final Logger logger = Logger.getLogger(RedisAOP.class); private static final Integer TIME_OUT = 30 ; //redis 存活時(shí)長 分鐘 @Resource private RedisTemplate redisTemplate; /** * @Title: queryCachePointcut * @Description: 定義切點(diǎn)為緩存注解 * @return void **/ @Pointcut("@within(com.ys.edu.annotation.RedisCache)") public void queryCachePointcut(){ } @Around("queryCachePointcut()") public Object Interceptor(ProceedingJoinPoint joinPoint) throws Throwable{ long beginTime = System.currentTimeMillis(); MethodSignature signature = (MethodSignature) joinPoint.getSignature(); //類路徑名 String classPathName = joinPoint.getTarget().getClass().getName(); //類名 String className = classPathName.substring(classPathName.lastIndexOf(".")+1,classPathName.length()); //獲取方法名 String methodName = signature.getMethod().getName(); String[] strings = signature.getParameterNames(); String key = className+"_"+methodName+"_"+Arrays.toString(strings); if((methodName.indexOf("select") != -1 && methodName.substring(0,6).equalsIgnoreCase("select")) || (methodName.indexOf("query") != -1 && methodName.substring(0,5).equalsIgnoreCase("query")) || (methodName.indexOf("get") != -1 && methodName.substring(0,3).equalsIgnoreCase("get"))){ Object data = getObject(beginTime,joinPoint,key); if(data != null){ return ResultUtils.success(data); } return joinPoint.proceed(); }else if((methodName.indexOf("add") != -1 && methodName.substring(0,3).equalsIgnoreCase("add")) || (methodName.indexOf("insert") != -1 && methodName.substring(0,6).equalsIgnoreCase("insert")) || (methodName.indexOf("update") != -1 && methodName.substring(0,6).equalsIgnoreCase("update"))){ Set<String> keys = redisTemplate.keys(className+"*"); redisTemplate.delete(keys); logger.warn("執(zhí)行方法 : [ "+methodName+" ] : 清除 key 包含 [ "+className+" ] 的緩存數(shù)據(jù)"); logger.warn("AOP 緩存切面處理 >>>> end 耗時(shí):" + (System.currentTimeMillis() - beginTime)); } // 調(diào)用原始方法 return joinPoint.proceed(); } /** * @Title: getObject * @Description: 使用key獲取數(shù)據(jù) 不存在則查詢添加 * @param beginTime : 切面開始時(shí)間 * @param joinPoint : 切面對象 * @param key : 獲取redis數(shù)據(jù)的key值 * @return java.lang.Object **/ private Object getObject(long beginTime,ProceedingJoinPoint joinPoint,String key) throws Throwable { ValueOperations<String, Object> operations = redisTemplate.opsForValue(); boolean hasKey = redisTemplate.hasKey(key); Object object = null; if(hasKey){ // 緩存中獲取到數(shù)據(jù),直接返回。 object = operations.get(key); logger.warn("從緩存中獲取到 key 為 ["+key+" ] : 的數(shù)據(jù) >>>> " + object.toString()); logger.warn("AOP 緩存切面處理 >>>> end 耗時(shí):" + (System.currentTimeMillis() - beginTime)); return object; } if(object == null) { // 緩存中沒有數(shù)據(jù),調(diào)用原始方法查詢數(shù)據(jù)庫 object = joinPoint.proceed(); operations.set(key, object, TIME_OUT, TimeUnit.MINUTES); // 設(shè)置超時(shí)時(shí)間30分鐘 logger.warn("向 Redis 添加 key 為 ["+key+" ] , 存活時(shí)長為 "+TIME_OUT+" min 的數(shù)據(jù) >>>> " + object.toString()); logger.warn("AOP 緩存切面處理 >>>> end 耗時(shí):" + (System.currentTimeMillis() - beginTime)); } return object; } @Autowired(required = false) public void setRedisTemplate(RedisTemplate redisTemplate) { RedisSerializer stringSerializer = new StringRedisSerializer();//序列化為String Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);//序列化為Json redisTemplate.setKeySerializer(stringSerializer); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setHashKeySerializer(stringSerializer); redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); this.redisTemplate = redisTemplate; } }
在想要使用redis緩存的controller類上添加 @RedisCache 注解.
切面方法則會切以select/get/query 開頭的查詢方法,獲取方法名和參數(shù)拼接為key,存到redis.
在執(zhí)行add/insert/update 開頭的方法時(shí),則清空該類下的所有緩存.
方法返回值格式統(tǒng)一實(shí)體類:
package com.ys.edu.bean; import java.io.Serializable; /** * @ClassName ResultBody * @description: RestFul API 方法返回值格式統(tǒng)一實(shí)體類 **/ public class ResultBody<T> implements Serializable { private static final long serialVersionUID = 694858559908048578L; private Integer code; private String msg; private Integer count = 0; private T data; public ResultBody(){} public ResultBody(Integer code, String msg,Integer count,T data) { this.code = code; this.msg = msg; this.count = count; this.data = data; } public ResultBody(Integer code, String msg,T data) { this.code = code; this.msg = msg; this.data = data; } /** * @Title: success * @Description: 成功 (無參) 默認(rèn) code : " 0 " msg : "請求成功" , count : 0 , data: null * @date 2018/11/29 10:28 **/ public ResultBody success(){ return success((T) null); } /** * @Title: success * @Description: 成功 默認(rèn) code : " 0 " msg : "請求成功" * @param count : 數(shù)據(jù)條數(shù) * @param data : 數(shù)據(jù) * @date 2018/11/29 11:46 **/ public ResultBody success(Integer count,T data){ return new ResultBody(0,"請求成功!",count,data); } /** * @Title: success * @Description: 成功 默認(rèn) code : " 0 " * @param msg : 提示信息 * @param count : 數(shù)據(jù)條數(shù) * @param data : 數(shù)據(jù) **/ public ResultBody success(String msg,Integer count,T data){ return new ResultBody(0,msg,count,data); } /** * @Title: success * @Description: 成功 默認(rèn) code : " 0 " , msg : "請求成功" * @param data : 數(shù)據(jù) **/ public ResultBody success(T data){ return new ResultBody(0,"請求成功!",data); } /** * @Title: success * @Description: 成功 默認(rèn) code : " 0 " * @param msg : 提示信息 * @param data : 數(shù)據(jù) * @date 2018/11/29 11:47 **/ public ResultBody success(String msg,T data){ return new ResultBody(0,msg,data); } /** * @Title: success * @Description: 成功 默認(rèn) code : " 0 " * @param code : 枚舉類代碼 * @param data : 數(shù)據(jù) **/ public ResultBody success(Code code,T data){ return new ResultBody(code.getCode(),code.getMsg(),data); } /** * @Title: success * @Description: 成功 默認(rèn) code : " 0 " * @param code : 枚舉類代碼 **/ public ResultBody success(Code code){ return new ResultBody(code.getCode(),code.getMsg(),null); } /** * @Title: error * @Description: 錯誤 默認(rèn) data : null * @param code : 錯誤代碼 * @param msg : 錯誤信息 **/ public ResultBody error(Integer code,String msg){ return new ResultBody(code,msg,null); } /** * @Title: error * @Description: 錯誤 默認(rèn) data : null * @param code : 枚舉類錯誤代碼 **/ public ResultBody error(Code code){ return new ResultBody(code.getCode(),code.getMsg(),null); } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public Integer getCount() { return count; } public void setCount(Integer count) { this.count = count; } public T getData() { return data; } public void setData(T data) { this.data = data; } }
自定義提示枚舉類:
package com.ys.edu.bean; /** * @ClassName Code * @description: 自定義提示枚舉類 **/ public enum Code { /** * @Description: 請求狀態(tài)碼 **/ SUCCESS(0,"請求成功"), ERROR(-1,"請求錯誤"); private Integer code; private String msg; public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } Code(Integer code, String msg){ this.code = code; this.msg = msg; } }
返回結(jié)果工具類:
package com.ys.edu.utils; import com.ys.edu.bean.Code; import com.ys.edu.bean.ResultBody; import com.ys.edu.entity.Page; import java.util.HashMap; import java.util.Map; /** * @ClassName ResultUtils * @description: 返回結(jié)果工具類 **/ public class ResultUtils { /** * @Title: success * @Description: 無參成功返回 默認(rèn)值 code : "0" , msg : "請求成功" , count : 0 , data : null **/ public static ResultBody success(){ return success((Object)null); } public static ResultBody success(Object object){ return success(0,object); } /** * @Title: success * @Description: 有參成功返回 默認(rèn)值 code : "0" , msg : "請求成功" * @param count : 數(shù)據(jù)條數(shù) * @param object : 數(shù)據(jù) **/ public static ResultBody success(Integer count,Object object){ return new ResultBody().success(count,object); } /** * @Title: success * @Description: 有參成功返回 默認(rèn)值 code : "0" * @param msg : 提示信息 * @param count : 數(shù)據(jù)條數(shù) * @param object : 數(shù)據(jù) **/ public static ResultBody success(String msg,Integer count,Object object){ return new ResultBody().success(msg,count,object); } /** * @Title: error * @Description: 有參成功返回 默認(rèn)值 code : "0" * @param code : * @param object : 數(shù)據(jù) **/ public static ResultBody success(Code code,Object object){ return new ResultBody().success(code,object); } /** * @Title: error * @Description: 有參成功返回 默認(rèn)值 code : "0" data : null * @param code : 枚舉類代碼 **/ public static ResultBody success(Code code){ return new ResultBody().success(code); } /** * @Title: error * @Description: 錯誤返回格式 默認(rèn)值 data : null * @param code : 錯誤代碼 **/ public static ResultBody error(Integer code,String msg){ return new ResultBody().error(code,msg); } /** * @Title: error * @Description: 錯誤返回格式 默認(rèn)值 data : null * @param code : 枚舉類錯誤代碼 **/ public static ResultBody error(Code code){ return new ResultBody().error(code); } /** * @Title: successByLimit * @Description: 分頁返回?cái)?shù)據(jù)格式 * @param page : 查詢的頁數(shù) * @param limit : 查詢的條數(shù) * @param totalNum : 數(shù)據(jù)總條數(shù) * @param curCount : 當(dāng)前頁條數(shù) * @param object : 查詢結(jié)果數(shù)據(jù) **/ public static ResultBody successByLimit(Integer page,Integer limit,Integer totalNum,Integer curCount,Object object){ Map<String,Object> map = new HashMap<>(); Page pageInfo = new Page(); pageInfo.setPage(page); pageInfo.setLimit(limit); pageInfo.setTotalNum(totalNum); pageInfo.setTotalPages((totalNum + limit - 1)/limit); map.put("page",pageInfo); map.put("data",object); return success(curCount,map); } }
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對億速云的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。