美文网首页
利用Spring的AOP,通过注解自动给方法添加缓存

利用Spring的AOP,通过注解自动给方法添加缓存

作者: 和平菌 | 来源:发表于2021-01-28 17:53 被阅读0次

    需求:如果入参一致的情况下,返回值一致,那么可以给该方法添加缓存。但是,如果挨个添加每次添加都需要开发、测试,浪费大量时间。
    解决方案:利用Spring的AOP,自动添加缓存功能

    实现步骤:
    1、定义注解

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD,ElementType.TYPE})
    public @interface AutoCache {
    
        /**
         * 过期时间,单位是秒,默认1分钟
         * @return
         */
        int expire() default 60;
    
        /**
         * 是否延期,如果选择是,每次访问都会续期expire时长
         * @return
         */
        boolean isDelay() default  false;
    
        String version() default "";
    }
    

    一共3个参数:
    过期时间
    是否延期
    方法的版本号

    2、AOP拦截器

    @Aspect
    @Component
    @Slf4j
    public class CacheIntercepter {
    
        public static final String CACHE_KEY_PREFIX = "AUTOCACHE";
        
        @Autowired
        private ResultCache resultCache;
    
        @Around("@annotation(com.heping.aopcache.AutoCache)")
        public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
            AutoCache methodCache = getAnnotation(joinPoint, AutoCache.class);
            String cacheKey = getCacheKey(joinPoint);
    
            String version = methodCache.version();
            if(version != null && version.length() > 0){
                cacheKey = cacheKey + version;
            }
    
            Object obj = resultCache.get(cacheKey);
            if (obj != null) {
                if(methodCache.isDelay()){
                    resultCache.expire(cacheKey, methodCache.expire());
                }
                log.info("自动从缓存获取结果,key [{}]", cacheKey);
                return obj;
            } else {
                log.debug("没有命中缓存,key [{}]", cacheKey);
                Object result = joinPoint.proceed(joinPoint.getArgs());
                if (result == null) {
                    log.error("从缓存获取到的结果为空,key [{}]", cacheKey);
                } else {
                    resultCache.save(cacheKey, result, methodCache.expire());
                }
                return result;
            }
        }
    
    
    
        private String getCacheKey(ProceedingJoinPoint joinPoint) {
            return Tool.format("{}-{}.{}",
                    CACHE_KEY_PREFIX,
                    joinPoint.getSignature().toString().split("\\s")[1],
                    StringUtils.join(joinPoint.getArgs(), ",")
            );
        }
    
        private <T extends Annotation> T getAnnotation(ProceedingJoinPoint jp, Class<T> clazz) {
            MethodSignature sign = (MethodSignature) jp.getSignature();
            Method method = sign.getMethod();
            return method.getAnnotation(clazz);
        }
    
    }
    
    

    其中ResultCache是对缓存读写的封装

    3、使用例子

    @AutoCache( expire = 10 * 60, isDelay = true, version = "v1")
        public String getName(String name){
            log.info("没有从缓存获取数据");
            return "jdtbi say:" + name;
        }
    

    每次修改了方法,逻辑改变的时候,我们只需要修改注解上的version的值,那么我们就会自动刷新缓存了

    相关文章

      网友评论

          本文标题:利用Spring的AOP,通过注解自动给方法添加缓存

          本文链接:https://www.haomeiwen.com/subject/badxtltx.html