SpringBoot AOP制御Redis自動キャッシュと更新


redisのjarパッケージをインポート

        
            org.springframework.boot
            spring-boot-starter-data-redis
            2.0.4.RELEASE
        

カスタムキャッシュ注記の作成
/**
 * @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 keys = redisTemplate.keys(className+"*");
            redisTemplate.delete(keys);
            logger.warn("     : [ "+methodName+" ] :     key    [ "+className+" ]      ");
            logger.warn("AOP        >>>> end   :" + (System.currentTimeMillis() - beginTime));
        }
        //       
        return joinPoint.proceed();
    }


    /**
     * @Title: getObject
     * @Description:   key              
     * @param beginTime :       
     * @param joinPoint :     
     * @param key :   redis   key 
     * @return java.lang.Object
     **/
    private Object getObject(long beginTime,ProceedingJoinPoint joinPoint,String key) throws Throwable {
        ValueOperations operations = redisTemplate.opsForValue();
        boolean hasKey = redisTemplate.hasKey(key);
        Object object = null;
        if(hasKey){
            //         ,    。
            object = operations.get(key);
            logger.warn("        key   ["+key+" ] :     >>>> " + object.toString());
            logger.warn("AOP        >>>> end   :" + (System.currentTimeMillis() - beginTime));
            return object;
        }
        if(object == null) {
            //        ,           
            object = joinPoint.proceed();
            operations.set(key, object, TIME_OUT, TimeUnit.MINUTES); //       30  
            logger.warn("  Redis    key   ["+key+" ] ,       "+TIME_OUT+" min     >>>> " + 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で始まるクエリーメソッドをカットし、メソッド名とパラメータの結合をkeyとしてredisに格納する.
add/insert/updateの先頭のメソッドを実行すると、クラス内のすべてのキャッシュが空になります.
メソッドは、値フォーマット統合エンティティクラスを返します.
package com.ys.edu.bean;

import java.io.Serializable;

/**
 * @ClassName ResultBody
 * @description:  RestFul API             
 **/
public class ResultBody 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 :     
     * @param data :    
     * @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 :      
     * @param data :     
     **/
    public ResultBody success(String msg,Integer count,T data){
        return new ResultBody(0,msg,count,data);
    }

    /**
     * @Title: success
     * @Description:          code : " 0 " , msg : "    "
     * @param data :    
     **/
    public ResultBody success(T data){
        return new ResultBody(0,"    !",data);
    }

    /**
     * @Title: success
     * @Description:          code : " 0 "
     * @param msg :      
     * @param data :    
     * @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 :    
     **/
    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:       
     **/
    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;
    }

}


結果ツールクラスを返します.
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:        
 **/
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 :      
     * @param object :   
     **/
    public static ResultBody success(Integer count,Object object){
        return new ResultBody().success(count,object);
    }

    /**
     * @Title: success
     * @Description:                code : "0"
     * @param msg :     
     * @param count :      
     * @param object :    
     **/
    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 :   
     **/
    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:         
     * @param page :      
     * @param limit :      
     * @param totalNum :      
     * @param curCount :      
     * @param object :       
     **/
    /*public static ResultBody successByLimit(Integer page,Integer limit,Integer totalNum,Integer curCount,Object object){
        Map 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);
    }*/

}