1. 程式人生 > >springboot 2.x 快取功能,基於redis封裝快取

springboot 2.x 快取功能,基於redis封裝快取

spring boot整合redis進行資料快取功能

        @Cacheable 表明Spring在呼叫方法之前,首先應該在快取中查詢方法的返回值。如果這個值能夠找到,就會返回快取的值。否則的話,這個方法就會被呼叫,返回值會放到快取之中

        @cacheput 表明Spring應該將方法的返回值放到快取中。在方法的呼叫前並不會 檢查快取,方法始終都會被呼叫

        @cacheevict 表明Spring應該在快取中清除一個或多個條目

        @caching 這是一個分組的註解,能夠同時應用多個其他的快取註解

        @cacheconfig 可以在類層級配置一些共用的快取配置

 

當然,spring已經封裝非常好了,我在之前實現了一個註解式redis快取,整體來說可用性還是不錯的,先分享出來,有時間在把springboot快取整合

/**
 * @liuxl
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
@Documented
public @interface RedisCache {

    /**
     * @Description: 如果name不為空,則以name為key,若name為空,則以類名:方法名為key
     * @Param:
     * @return:
     */
    String key();

    /**
     * @Description: 資料快取時間單位s秒
     * @Param:  預設10分鐘
     * @return:
     */
    int cacheTime() default 600;

}

 

import com.alibaba.fastjson.JSON;
import java.lang.reflect.Method;


import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @author liuxl
 */
@Aspect
@Component
@Order(-9)
public class RedisCacheAspect {

    private Logger logger = LoggerFactory.getLogger(this.getClass());


    @Around("@annotation(cache)")
    public Object redisCache(ProceedingJoinPoint pjp,RedisCache cache) throws Throwable {
        String redisResult = "";
        String className = pjp.getTarget().getClass().getName();
        Signature signature = pjp.getSignature();
        if(!(signature instanceof MethodSignature)){
            throw  new IllegalArgumentException();
        }
        MethodSignature methodSignature = (MethodSignature) signature;
        String methodName = pjp.getSignature().getName();
        Method method = pjp.getTarget().getClass().getMethod(methodSignature.getName(),methodSignature.getParameterTypes());
        String dictName=method.getAnnotation(RedisCache.class).key();
        String key = StringUtils.isNotBlank(dictName)?dictName:genKey(className,methodName);
        logger.info("生成的key[{}]",key);
        Object[] args = pjp.getArgs();
        int cacheTime = method.getAnnotation(RedisCache.class).cacheTime();
        Object result = null;
        if(RedisUtils.size(key)==0L) {
            logger.info("快取未命中key=[{}]",key);
            result = pjp.proceed(args);
            redisResult = JSON.toJSONString(result);
            RedisUtils.set(key,redisResult,cacheTime);
        } else{
            //快取命中
            logger.info("快取命中key=[{}]",key);
            redisResult = RedisUtils.get(key);
            //得到被代理方法的返回值型別
            Class returnType = method.getReturnType();
            result = JSON.parseObject(redisResult,returnType);
        }
        return result;
    }

    /**
     * @Description: 生成key
     * @Param:
     */
    private String genKey(String className, String methodName) {
        return StringUtils.substringAfterLast(className,".").concat(methodName);

    }

}