Spring Cache 笔记
@(Java ThirdParty)[Spring Cache]
Spring Cache Abstraction
简介
Spring Cache提供了对底层缓存使用的抽象,通过注解的方式使用缓存,减少了对原有的侵入性,通过一个抽象层,分离了不同后端缓存的实现,在不改变代码的前提下,可以切换底层缓存的实现。
Cache只有应用于幂等性的方法,即同样的输入,返回同样的数据(在数据没有变更时)。
在多线程的情况下,由Cache底层实现类保存线程安全。
Cache 两次读取数据流程(第一次miss,第二次hit):

注解使用说明
Cacheable
@Cacheable注解用于指示缓存该方法的返回数据。
该注解的属性中,需要指定一个name,用于绑定到低层的缓存(比如,底层使用的是CurrentHashMap,那这个name就是用于指示到底是哪个Map,一般来说,一个方法或者类对应一个Map)
Key Generator
KeyGenerator用于生成Cache Key,默认提供SimpleKeyGenerator计算方法如下:
- 如果没有参数,就返回SimpleKey.EMPTY
- 如果有一个参数,就返回该参数实例
- 如果有多个方法,就返回一个SimpleKey,该实例包含了所有的参数
默认提供的Generator使用hashCode以及equals来计算,所以对于复杂的类,需要实现对应的方法。或者也可以通过自定义KeyGenerator来实现。(使用keyGenerator属性来指定)
除了使用KeyGenerator外,还可以使用key属性来指定(两者只能使用一个,否则会抛异常)
Key属性
通过SpEL来生成Key,如:
@Cacheable(cacheNames="books", key="#isbn")
public Book findBook(ISBN isbn, boolean check);
@Cacheable(cacheNames="books", key="#isbn.rawNumber")
public Book findBook(ISBN isbn, boolean check);
Cache Resolution
CacheResolver
Sync
Cache缓存的时候,如果多次同时调用,当没有命中的时候,会直接调用方法计算,这会导致重复计算,以及缓存没有生效,这时就需要采用同步的方式,一个方法调用,其余的在等待。
可以通过sync=“true”属性来指定(默认为false)
注:这个特性取决于底层的实现(在Cache Aop读取流程中并没有加锁处理)
条件式缓存
当需要在特定参数情况下才缓存的时候,就可以使用。通过condition来计算,如果为true,则缓存,否则不缓存,如:
@Cacheable(cacheNames="books", condition="#name.length < 32")
public Book findBook(String name);
SpEL Cache表达式上下文
CachePut
@CachePut用于更新缓存
注:不能和@Cacheable同时使用。
CacheEvict
@CacheEvict注解用于淘汰缓存,其中可以通过cacheNames和key属性来淘汰指定的Entry,也可以使用cacheNames和allEntries=true来淘汰掉所有的Entries。
beforeInvocation属性
这个属性用于控制是在方法调用前还是调用后再淘汰缓存,如果是调用后,在抛出异常时,则不会淘汰(默认为false)。
这里也涉及了缓存写淘汰策略。
Caching
@Caching用于将多个操作组合起来,如CacheEvict和CachePut组合
CacheConfig
类级别的注解,用于定义一些该类的通用配置,可以被方法级别的配置覆盖
三个层级配置:
- 全局配置,CacheManager/KeyGenerator
- 类级别配置
- 方法级别
开启Cache注解功能
@EnableCaching置于@Configuration配置上,或者在XML加入配置:
<cache:annotation-driven />
注:如果把<cache:annotation-driven />放在WebApplicationContext中的话,那就只会扫描controllers,而不是services
Cache存储配置
Spring Cache提供了多个不同的存储集成,使用的时候,只需要定义对应的CacheManager即可。
如下:
- JDK ConcurrentMap-based Cache.(使用ConcurrentHashMap作为底层存储)
- EhCache-base Cache
- Caffeine Cache
- Guava Cache
- GemFire-base Cache
- JSR-107 Cache
Spring Cache可以配置多个Cache实现(使用CompositeCacheManager)
注:如果上述的集成都不满足,则可以自定义实现,通过实现CacheManager和Cache即可。
Cache Aop执行流程
在下述的所有操作中,都没有同步或者锁的操作,即如果要实现相同query防止重复执行,则需要底层缓存库支持。
注:这里会有并发问题,举个例子:查询个人信息。当缓存没有命中的时候,会执行实际的方法,然后将结果缓存起来。在这中间,如果作了更新的操作,并且执行完CacheEvict,然后上述查询结果再缓存起来,就会导致读取到脏数据。所以缓存的时间也需要控制好。

参考资料
- spring-framework-reference - ch36
- spring cache 源码
Spring Cache 笔记的更多相关文章
- spring 入门笔记(一)
最近学习spring 通过笔记形式加深自己对spring的理解,也希望能跟各位入门者分享和讨论. 一.下载spring 下载spring也费了不少功夫,目前还没从spring官网找到下载入口,我从下面 ...
- struts2,hibernate,spring整合笔记(2)
上一话struts2,hibernate,spring整合笔记(1) 接下来继续 配置完struts之后就要开始hibernate的配置 hibernate的环境并不依赖web开发环境,在我第一次配置 ...
- Spring读书笔记——bean创建(上)
通过<Spring读书笔记--bean加载>和<Spring读书笔记--bean解析>,我们明白了两件事. Spring如何加载消化一个xml配置文件 Spring如何将xml ...
- Spring读书笔记——bean创建(下)
有关Spring加载bean系列,今天这是最后一篇了,主要接上篇对于从Spring容器中获取Bean的一些细节实现的补充. <Spring读书笔记--bean加载>--Spring如何加载 ...
- 【Spring学习笔记-MVC-5】利用spring MVC框架,实现ajax异步请求以及json数据的返回
作者:ssslinppp 时间:2015年5月26日 15:32:51 1. 摘要 本文讲解如何利用spring MVC框架,实现ajax异步请求以及json数据的返回. Spring MV ...
- Spring cache简单使用guava cache
Spring cache简单使用 前言 spring有一套和各种缓存的集成方式.类似于sl4j,你可以选择log框架实现,也一样可以实现缓存实现,比如ehcache,guava cache. [TOC ...
- 注释驱动的 Spring cache 缓存介绍
概述 Spring 3.1 引入了激动人心的基于注释(annotation)的缓存(cache)技术,它本质上不是一个具体的缓存实现方案(例如 EHCache 或者 OSCache),而是一个对缓存使 ...
- [转]注释驱动的 Spring cache 缓存介绍
原文:http://www.ibm.com/developerworks/cn/opensource/os-cn-spring-cache/ 概述 Spring 3.1 引入了激动人心的基于注释(an ...
- Spring Security笔记:HTTP Basic 认证
在第一节 Spring Security笔记:Hello World 的基础上,只要把Spring-Security.xml里改一个位置 <http auto-config="true ...
随机推荐
- (NO.00003)iOS游戏简单的机器人投射游戏成形记(十七)
现在玩家选择机器人后,可以在屏幕上或手臂上点击来移动robot's arm了. 但是玩家选择一个机器人后没有视觉效果来表明哪个机器人被选中.玩家做了一个操作后没有视觉反馈会惹恼强迫症用户滴 ;) 这篇 ...
- Gradle 1.12 翻译——第十二章 使用Gradle 图形用户界面
有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com ...
- Java 8新特性探究(二)类型注解和重复注解
本文将介绍java 8的第二个特性:类型注解. 注解大家都知道,从java5开始加入这一特性,发展到现在已然是遍地开花,在很多框架中得到了广泛的使用,用来简化程序中的配置.那充满争议的类型注解究竟是什 ...
- python循环for,range,xrange;while
>>>range(1,5)#代表从1到5(不包含5) [1,2,3,4] >>>range(1,5,2)#代表从1到5,间隔2(不包含5) [1,3] >&g ...
- bash:chkconfig:command not found
1尝试sudo/su rootsudo chkconfig --list2上述方法不行,请检查是否安装chkconfigrpm -qa |grep chkconfigubuntu上默认是不支持chkc ...
- DB 查询分析器 方便地创建DB2自定义函数
DB 查询分析器 方便地创建DB2自定义函数 马根峰 (广东联合电子服务股份有限公司, 广州 510300) 摘要 ...
- Workflow相关表简单分析
静态定义表(没有ITEM_KEY,因为ITEM_KEY代表一个wf实例) --获取item_type定义. SELECT * FROM wf_item_types t WHEREt.name= 'CU ...
- 【一天一道LeetCode】#78. Subsets
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...
- HEVC,VP9,x264性能对比
Dan Grois等人在论文<Performance Comparison of H.265/MPEG-HEVC, VP9, andH.264/MPEG-AVC Encoders>中,比较 ...
- 解决unbuntu14.04上的eclipse自动退出的问题
新安装的ubuntu14.04版,把以前12.04上正常使用的eclipse拷贝到14.04上后,启动eclipse后,输入代码时出现点"."提示符就会自动重启. jdk是1.7. ...