zoukankan      html  css  js  c++  java
  • Spring Cache 源码解析

    这个类实现了Spring的缓存拦截器 org.springframework.cache.interceptor.CacheInterceptor

    @SuppressWarnings("serial")
    public class CacheInterceptor extends CacheAspectSupport implements MethodInterceptor, Serializable {
    
        private static class ThrowableWrapper extends RuntimeException {
            private final Throwable original;
    
            ThrowableWrapper(Throwable original) {
                this.original = original;
            }
        }
    
        //这是进行对目标方法的拦截
        public Object invoke(final MethodInvocation invocation) throws Throwable {
            Method method = invocation.getMethod();
    
            //封装一个回调对象 多目标方法进行调用
            Invoker aopAllianceInvoker = new Invoker() {
                public Object invoke() {
                    try {
                        return invocation.proceed();
                    } catch (Throwable ex) {
                        throw new ThrowableWrapper(ex);
                    }
                }
            };
    
            try {
                //调用父类的execute方法 进行缓存的逻辑判断处理
                return execute(aopAllianceInvoker, invocation.getThis(), method, invocation.getArguments());
            } catch (ThrowableWrapper th) {
                throw th.original;
            }
        }
    }

    下面分析execute方法

        protected Object execute(Invoker invoker, Object target, Method method, Object[] args) {
            //判断当前对象是否已经初始化完毕
            if (!this.initialized) {
                return invoker.invoke();
            }
    
            //获得目标类型
            Class<?> targetClass = AopProxyUtils.ultimateTargetClass(target);
            if (targetClass == null && target != null) {
                targetClass = target.getClass();
            }
            //获得缓存操作细节对象
            final Collection<CacheOperation> cacheOp = getCacheOperationSource().getCacheOperations(method, targetClass);
    
            //判断是否为空 不为空则进行下面的缓存逻辑处理
            if (!CollectionUtils.isEmpty(cacheOp)) {
                Map<String, Collection<CacheOperationContext>> ops = createOperationContext(cacheOp, method, args, target, targetClass);
    
                // 调用目标方法之前的清除缓存动作
                inspectBeforeCacheEvicts(ops.get(EVICT));
    
                // follow up with cacheable
                CacheStatus status = inspectCacheables(ops.get(CACHEABLE));
    
                Object retVal = null;
                Map<CacheOperationContext, Object> updates = inspectCacheUpdates(ops.get(UPDATE));
    
                if (status != null) {
                    if (status.updateRequired) {
    
                        updates.putAll(status.cUpdates);
                    }
                    // return cached object
                    // 返回缓存当中的数据
                    else {
                        return status.retVal;
                    }
                }
                //调用目标对象 拿到返回值
                retVal = invoker.invoke();
    
                // 调用目标方法之后的清除缓存动作
                inspectAfterCacheEvicts(ops.get(EVICT));
    
                //更新缓存,或将返回结果放入缓存
                if (!updates.isEmpty()) {
                    update(updates, retVal);
                }
                //返回结果
                return retVal;
            }
    
            //上面判断如果缓存操作细节对象为空 则直接调用目标对象处理。
            return invoker.invoke();
        }
  • 相关阅读:
    显示文件本地文件夹
    Select Dependencies选择依赖项
    搜索小技巧
    783. Minimum Distance Between BST Nodes BST节点之间的最小距离
    5. Longest Palindromic Substring 最长的回文子串
    12. Integer to Roman 整数转罗马数字
    3. Longest Substring Without Repeating Characters 最长的子串不重复字符
    539. Minimum Time Difference 最小时差
    43. Multiply Strings 字符串相乘
    445. Add Two Numbers II 两个数字相加2
  • 原文地址:https://www.cnblogs.com/daxin/p/3568441.html
Copyright © 2011-2022 走看看