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 Cache 源码解析的更多相关文章
- spring事务源码解析
前言 在spring jdbcTemplate 事务,各种诡异,包你醍醐灌顶!最后遗留了一个问题:spring是怎么样保证事务一致性的? 当然,spring事务内容挺多的,如果都要讲的话要花很长时间, ...
- Spring IoC源码解析之invokeBeanFactoryPostProcessors
一.Bean工厂的后置处理器 Bean工厂的后置处理器:BeanFactoryPostProcessor(触发时机:bean定义注册之后bean实例化之前)和BeanDefinitionRegistr ...
- Spring系列(六):Spring事务源码解析
一.事务概述 1.1 什么是事务 事务是一组原子性的SQL查询,或者说是一个独立的工作单元.要么全部执行,要么全部不执行. 1.2 事务的特性(ACID) ①原子性(atomicity) 一个事务必须 ...
- Spring Security源码解析一:UsernamePasswordAuthenticationFilter之登录流程
一.前言 spring security安全框架作为spring系列组件中的一个,被广泛的运用在各项目中,那么spring security在程序中的工作流程是个什么样的呢,它是如何进行一系列的鉴权和 ...
- Spring cache源码分析
Spring cache是一个缓存API层,封装了对多种缓存的通用操作,可以借助注解方便地为程序添加缓存功能. 常见的注解有@Cacheable.@CachePut.@CacheEvict,有没有想过 ...
- Spring IoC源码解析之getBean
一.实例化所有的非懒加载的单实例Bean 从org.springframework.context.support.AbstractApplicationContext#refresh方法开发,进入到 ...
- Spring系列(五):Spring AOP源码解析
一.@EnableAspectJAutoProxy注解 在主配置类中添加@EnableAspectJAutoProxy注解,开启aop支持,那么@EnableAspectJAutoProxy到底做了什 ...
- Spring系列(三):Spring IoC源码解析
一.Spring容器类继承图 二.容器前期准备 IoC源码解析入口: /** * @desc: ioc原理解析 启动 * @author: toby * @date: 2019/7/22 22:20 ...
- Spring Boot系列(四):Spring Boot源码解析
一.自动装配原理 之前博文已经讲过,@SpringBootApplication继承了@EnableAutoConfiguration,该注解导入了AutoConfigurationImport Se ...
随机推荐
- delphi實現按键精靈的功能
unit kbKernel; interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Fo ...
- DPDK架构与特点
当年在某公司实习的时候,当时老大给了我一份DPDK的文档,说是将来很有用,熟悉DPDK对能力提高也有帮助,就试着翻译了 <Intel DPDK Getting Started Guide> ...
- mysql 必须掌握的工具pt-query-digest安装
mysql 必须掌握的工具pt-query-digest 古人云:工欲善其事,必先利其器.作为一名优秀的mysql dba也需要有掌握几个好用的mysql管理工具,所以我也一直在整理和查找一些能够便于 ...
- iOS 即时通讯,从入门到 “放弃”?
原文链接:http://www.jianshu.com/p/2dbb360886a8 本文会用实例的方式,将 iOS 各种 IM 的方案都简单的实现一遍.并且提供一些选型.实现细节以及优化的建议. — ...
- 将Log4J的日志内容发送到agent的source
项目中使用log4j打印的内容同时传输到flume 1.flume端 flume的agent配置内容如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 a1.sour ...
- Spring +quartz获取ApplicationContext上下文
job存在数据库中,能够进行动态的增增删改查,近期遇到了怎样获取ApplicationContext上下文的问题.解决的方法例如以下 applicationContext-quartz.xml < ...
- Python fabs() 函数
描述 fabs() 方法返回数字的绝对值,如math.fabs(-10) 返回10.0. fabs() 函数类似于 abs() 函数,但是他有两点区别: abs() 是内置函数. fabs() 函数在 ...
- mysql update常见实例
在MySQL中使用update语句的时候,Where条件或者值都可以使用子查询,比如: ) ); 但是如果子查询和更新的表是同一个表的话,MySQL会报如下的错误:中涉及到的子查询要格外注意 Erro ...
- unity5 创建material
在material文件夹下 unity5中新创建的material默认如下 开始我不知道贴图应该加在哪儿.于是跳过教程上这一步,直接去选shader: 在这个shader下很明显看到加贴图的地方了: ...
- quick cocos2dx 3.x 配置win32工程
公司项目主体部分用c++,而ui部分用lua写,所以选择了用quick框架.项目先开发了ios/mac版,这两天试着配置其win32工程,遇到一些问题,记录一下(纯c++版本cocos2dx配置方法应 ...