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();
        }
  • 相关阅读:
    线程基础知识归纳
    并发编程情况下几个相应问题简介
    Spring Security的RBAC数据模型嵌入
    Mysql插入中文的字段内容时乱码的解决方法
    部分排序算法总结
    sendEmail 阿里云使用587端口
    linux服务器关闭ipv6 方法
    centos 6.8 安装git 报错
    强大的xargs
    nfs环境搭建报错clnt_create: RPC: Program not registered
  • 原文地址:https://www.cnblogs.com/daxin/p/3568441.html
Copyright © 2011-2022 走看看