这个类实现了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 Cache 源码解析的更多相关文章

  1. spring事务源码解析

    前言 在spring jdbcTemplate 事务,各种诡异,包你醍醐灌顶!最后遗留了一个问题:spring是怎么样保证事务一致性的? 当然,spring事务内容挺多的,如果都要讲的话要花很长时间, ...

  2. Spring IoC源码解析之invokeBeanFactoryPostProcessors

    一.Bean工厂的后置处理器 Bean工厂的后置处理器:BeanFactoryPostProcessor(触发时机:bean定义注册之后bean实例化之前)和BeanDefinitionRegistr ...

  3. Spring系列(六):Spring事务源码解析

    一.事务概述 1.1 什么是事务 事务是一组原子性的SQL查询,或者说是一个独立的工作单元.要么全部执行,要么全部不执行. 1.2 事务的特性(ACID) ①原子性(atomicity) 一个事务必须 ...

  4. Spring Security源码解析一:UsernamePasswordAuthenticationFilter之登录流程

    一.前言 spring security安全框架作为spring系列组件中的一个,被广泛的运用在各项目中,那么spring security在程序中的工作流程是个什么样的呢,它是如何进行一系列的鉴权和 ...

  5. Spring cache源码分析

    Spring cache是一个缓存API层,封装了对多种缓存的通用操作,可以借助注解方便地为程序添加缓存功能. 常见的注解有@Cacheable.@CachePut.@CacheEvict,有没有想过 ...

  6. Spring IoC源码解析之getBean

    一.实例化所有的非懒加载的单实例Bean 从org.springframework.context.support.AbstractApplicationContext#refresh方法开发,进入到 ...

  7. Spring系列(五):Spring AOP源码解析

    一.@EnableAspectJAutoProxy注解 在主配置类中添加@EnableAspectJAutoProxy注解,开启aop支持,那么@EnableAspectJAutoProxy到底做了什 ...

  8. Spring系列(三):Spring IoC源码解析

    一.Spring容器类继承图 二.容器前期准备 IoC源码解析入口: /** * @desc: ioc原理解析 启动 * @author: toby * @date: 2019/7/22 22:20 ...

  9. Spring Boot系列(四):Spring Boot源码解析

    一.自动装配原理 之前博文已经讲过,@SpringBootApplication继承了@EnableAutoConfiguration,该注解导入了AutoConfigurationImport Se ...

随机推荐

  1. 很轻很强大:轻量级桌面环境比较(转自linuxeden)

    这天你终于下定决心购买了一台流行的 Netbook ,与往常装机一样,直接安装心爱的 Linux 发行版.好不容易安装完成了,却发现平日启动飞快的应用程序在 Netbook 上怎么都跑不快.怎么办呢? ...

  2. QRCode - 二维码识别与生成

    来源:Yi'mouleng(@丶伊眸冷) 链接:http://t.cn/R40WxcM 前言 有关二维码的介绍,我这里不做过多说明, 可以直接去基维百科查看,附上链接QR code(https://e ...

  3. Extending_and_embedding_php翻译

    http://blog.csdn.net/lgg201 博客翻译了Extending_and_embedding_php

  4. 阿里云ECS服务器Linux环境下配置php服务器(一)--基础配置篇

    开始安装软件了,我们需要安装的软件有apache,php和MySQL. ps:如果你购买的是北京的服务器,有个安全组需要设置,我全部用的默认设置,暂时还没发现会有什么影响. 首先关闭SELINUX(S ...

  5. Android:GridView中实现点击Item变色,再点击还原。

    使用GridView时想实现点击其中的一个Item,该Item改变背景,再次点击Item变回原来的背景,网上搜了很多资料都没有看到类似的案例,但还是有所启发,现来分享我的做法. 首先,首先为GridV ...

  6. VS2010中遇到_WIN32_WINNT not defined

    VS2010中编程时遇到这个问题 _WIN32_WINNT not defined. Defaulting to _WIN32_WINNT_MAXVER (see WinSDKVer.h) 解决办法: ...

  7. Mysql multi实现mysql双实例

    Mysql multi实现mysql双实例 1.添加mysql用户 以root登录,新建mysql用户组 groupadd mysql useradd -d /data/mariadb -g mysq ...

  8. Maven install 报错: Failed to execute goalorg.apache.maven.plugins:maven-gpg-plugin:1.4:sign (sign-art

    执行 Maven install 时报错: Failed to execute goalorg.apache.maven.plugins:maven-gpg-plugin:1.4:sign (sign ...

  9. PHPEXCEL导出excel表格中长数字文本自动转为科学计数法的解决办法

    方法一:前面加空格 $objActSheet->setCellValue('A1', ' '.'330602198804224688'); 方法二: $objActSheet->setCe ...

  10. 2015小米暑期实习笔试题_风口的猪-中国牛市(dp)

    风口之下.猪都能飞.当今中国股市牛市,真可谓"错过等七年". 给你一个回想历史的机会,已知一支股票连续n天的价格走势,以长度为n的整数数组表示,数组中第i个元素(prices[i] ...