最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot AOP控制Redis自動緩存和更新的示例

 更新時間:2019年01月05日 08:58:01   作者:丶Melody  
今天小編就為大家分享一篇關(guān)于SpringBoot AOP控制Redis自動緩存和更新的示例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧

導(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 存活時長 分鐘
  @Resource
  private RedisTemplate redisTemplate;
  /**
   * @Title: queryCachePointcut
   * @Description: 定義切點為緩存注解
   * @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 耗時:" + (System.currentTimeMillis() - beginTime));
    }
    // 調(diào)用原始方法
    return joinPoint.proceed();
  }
  /**
   * @Title: getObject
   * @Description: 使用key獲取數(shù)據(jù) 不存在則查詢添加
   * @param beginTime : 切面開始時間
   * @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 耗時:" + (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è)置超時時間30分鐘
      logger.warn("向 Redis 添加 key 為 ["+key+" ] , 存活時長為 "+TIME_OUT+" min 的數(shù)據(jù) >>>> " + object.toString());
      logger.warn("AOP 緩存切面處理 >>>> end 耗時:" + (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 開頭的方法時,則清空該類下的所有緩存.

方法返回值格式統(tǒng)一實體類:

package com.ys.edu.bean;
import java.io.Serializable;
/**
 * @ClassName ResultBody
 * @description: RestFul API 方法返回值格式統(tǒng)一實體類
 **/
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: 成功 (無參) 默認 code : " 0 " msg : "請求成功" , count : 0 , data: null
   * @date 2018/11/29 10:28
   **/
  public ResultBody success(){
    return success((T) null);
  }
  /**
   * @Title: success
   * @Description:  成功  默認 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: 成功  默認 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: 成功  默認 code : " 0 " , msg : "請求成功"
   * @param data : 數(shù)據(jù)
   **/
  public ResultBody success(T data){
    return new ResultBody(0,"請求成功!",data);
  }
  /**
   * @Title: success
   * @Description: 成功  默認 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: 成功  默認 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: 成功  默認 code : " 0 "
   * @param code : 枚舉類代碼
   **/
  public ResultBody success(Code code){
    return new ResultBody(code.getCode(),code.getMsg(),null);
  }
  /**
   * @Title: error
   * @Description: 錯誤  默認 data : null
   * @param code : 錯誤代碼
   * @param msg : 錯誤信息
   **/
  public ResultBody error(Integer code,String msg){
    return new ResultBody(code,msg,null);
  }
  /**
   * @Title: error
   * @Description: 錯誤  默認 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: 無參成功返回  默認值 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: 有參成功返回  默認值 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: 有參成功返回  默認值 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: 有參成功返回   默認值 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: 有參成功返回   默認值 code : "0" data : null
   * @param code : 枚舉類代碼
   **/
  public static ResultBody success(Code code){
    return new ResultBody().success(code);
  }
  /**
   * @Title: error
   * @Description: 錯誤返回格式   默認值 data : null
   * @param code : 錯誤代碼
   **/
  public static ResultBody error(Integer code,String msg){
    return new ResultBody().error(code,msg);
  }
  /**
   * @Title: error
   * @Description: 錯誤返回格式   默認值 data : null
   * @param code : 枚舉類錯誤代碼
   **/
  public static ResultBody error(Code code){
    return new ResultBody().error(code);
  }
  /**
   * @Title: successByLimit
   * @Description: 分頁返回數(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í)價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接

相關(guān)文章

  • SpringBoot多租戶配置與實現(xiàn)示例

    SpringBoot多租戶配置與實現(xiàn)示例

    本文詳細介紹了在SpringBoot中實現(xiàn)多租戶架構(gòu)的方法和步驟,包括配置數(shù)據(jù)源、Hibernate攔截器、租戶解析器等,以共享數(shù)據(jù)庫、共享數(shù)據(jù)表的方式,確保數(shù)據(jù)隔離和安全性,感興趣的可以了解一下
    2024-09-09
  • Java設(shè)計模式之單例模式簡單解析

    Java設(shè)計模式之單例模式簡單解析

    這篇文章主要介紹了Java設(shè)計模式之單例模式簡單解析,單例模式的優(yōu)點在于在內(nèi)存中某個類只有一個實例,減少了內(nèi)存的開銷,尤其是頻繁的創(chuàng)建和銷毀實例,避免對資源的多重暫用,需要的朋友可以參考下
    2023-12-12
  • Java JUnit 使用及常用注解

    Java JUnit 使用及常用注解

    JUnit是Java開發(fā)中必不可少的測試框架之一,它可以幫助您編寫高質(zhì)量、可維護的單元測試,本文介紹了JUnit的基本用法、常用注解、測試套件和參數(shù)化測試等內(nèi)容,希望對您的測試工作有所幫助,感興趣的朋友一起看看吧
    2023-12-12
  • Linux實時查看Java接口數(shù)據(jù)的案例方法

    Linux實時查看Java接口數(shù)據(jù)的案例方法

    在Linux系統(tǒng)中實時查看Java接口數(shù)據(jù)通常涉幾個步驟,通過示例代碼說明如何使用Python的requests庫和Linux的cron作業(yè)來定期查詢Java應(yīng)用程序的接口并打印結(jié)果,感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • Java中生成唯一ID的方法示例

    Java中生成唯一ID的方法示例

    這篇文章主要介紹了Java中生成唯一ID的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • Java String字符串內(nèi)容實現(xiàn)添加雙引號

    Java String字符串內(nèi)容實現(xiàn)添加雙引號

    這篇文章主要介紹了Java String字符串內(nèi)容實現(xiàn)添加雙引號,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • 通過Maven下載依賴Jar包的流程分享

    通過Maven下載依賴Jar包的流程分享

    本文主要介紹了Maven下載依賴Jar包的詳細流程,包括輸入Maven倉庫的官方地址、搜索依賴Jar包、選擇版本、復(fù)制和粘貼Maven依賴到pom文件中下載依賴Jar包
    2025-02-02
  • Java基于ShardingSphere實現(xiàn)分庫分表的實例詳解

    Java基于ShardingSphere實現(xiàn)分庫分表的實例詳解

    ShardingSphere?已于2020年4月16日成為?Apache?軟件基金會的頂級項目,?它們均提供標準化的數(shù)據(jù)水平擴展、分布式事務(wù)和分布式治理等功能,可適用于如?Java?同構(gòu)、異構(gòu)語言、云原生等各種多樣化的應(yīng)用場景,對ShardingSphere分庫分表相關(guān)知識感興趣的朋友一起看看吧
    2022-03-03
  • Spring Boot Admin 的使用詳解

    Spring Boot Admin 的使用詳解

    這篇文章主要介紹了Spring Boot Admin 的使用詳解,Spring Boot Admin 用于監(jiān)控基于 Spring Boot 的應(yīng)用,有興趣的可以了解一下
    2017-09-09
  • Spring AOP源碼深入分析

    Spring AOP源碼深入分析

    這篇文章主要介紹了Spring AOP源碼,AOP(Aspect Orient Programming),直譯過來就是 面向切面編程,AOP 是一種編程思想,是面向?qū)ο缶幊蹋∣OP)的一種補充
    2023-01-01

最新評論

瓦房店市| 襄垣县| 垦利县| 乌拉特中旗| 舒城县| 新乐市| 贺兰县| 米林县| 吉水县| 红桥区| 德保县| 辽中县| 济阳县| 赞皇县| 衡东县| 崇州市| 历史| 荥阳市| 白河县| 新和县| 广河县| 濮阳县| 昌乐县| 西藏| 禄丰县| 无锡市| 中江县| 四会市| 瑞丽市| 广州市| 永修县| 海盐县| 建德市| 屯留县| 东乌| 亚东县| 百色市| 兴山县| 休宁县| 吴堡县| 嵊州市|