• 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();
        }
  • 相关阅读:
    easyui datetimebox 日期控件绑定双击日期选择时间
    js 中call和apply的应用
    js中数组的合并和对象的合并
    flex也可以让背景透明
    收集了一些as的面试题,给HR准备的
    [转]PureMVC的十个小提示
    12个Flex常用功能代码
    43个热门Flex和ActionScript 3.0 APIs,技巧和工具[转]
    转载+原创PureMVC 实例讲解
    PureMVC使用时的注意事项
  • 原文地址:https://www.cnblogs.com/daxin/p/3568441.html
Copyright © 2020-2023  润新知