官方文档 8.0
Spring为不同缓存做了一层抽象,这里通过阅读文档以及源码会对使用以及原理做一些学习笔记。
1.简介
从3.1版开始,Spring Framework提供了对现有Spring应用程序透明地添加缓存的支持。 与事务支持类似,缓存抽象允许一致地使用各种缓存解决方案,而对代码的影响最小。
从Spring 4.1开始,通过JSR-107注释和更多自定义选项的支持,缓存抽象得到了显着改进。
1.1cache和buffer
从术语上看,"buffer"和"cache",可以互相被替换.但是,他们确实代表着不同的事情.
传统上,一个buffer被用来作为快数据和慢数据之间的临时存储.因为快速的一方需要等待慢的一方(会影响性能),buffer通过允许整块数据一次移动而不是一小块数据一点一点移动来缓解压力. 这个数据只会从buffer中被写入或者读出一次.此外,buffers对总对一方可以见.
Cache,则相反,通过定义,隐藏,并且不会让对方意识到它的存在.它同样提高性能,但是这是让相同数据在同时以快速的方式被多次读取来实现的.
可以通过 这个链接来看详细的不同的解释.
2.缓存抽象
缓存抽象的核心是将缓存应用于Java方法,从而减少了基于缓存中可用信息的执行次数。也就是说,每次调用目标方法时,抽象都会应用缓存行为检查方法是否已经为给定的参数执行。如果有,则返回缓存的结果,而不必执行实际的方法;如果没有,则执行方法,缓存结果并返回给用户,以便在下次调用方法时返回缓存的结果。这样,对于给定的一组参数,昂贵的方法(CPU或IO绑定)只能执行一次,并且结果可以重用,而不必实际再次执行该方法。缓存逻辑被透明地应用,没有任何对调用程序的干扰。
缓存抽象提供了其他缓存相关的操作,比如更新缓存的内容或者删除一个或者全部.如果缓存在处理数据的过程中经常改变,这些操作将非常有用.
就像Spring Framework中的其他服务一样,缓存服务是一种抽象(不是缓存实现),需要使用实际存储来存储缓存数据 - 也就是说,抽象使开发人员不必编写缓存相关逻辑,但它也不提供实际的数据存储能力。
通过接口 org.springframework.cache.Cache(缓存)和org.springframework.cache.CacheManager(缓存管理器) 实现缓存的抽象
这个抽象的一些实现可以直接使用:基于JDK java.util.concurrent.ConcurrentMap的缓存(即默认的缓存是基于JVM的ConcurrentMap),Ehcache 2.x,Gemfire缓存,Caffeine,符合和JSR-107的缓存(例如Ehcache 3.x)。 有关插入其他缓存存储/提供程序的更多信息,请参阅插入不同的后端缓存。
3.spring缓存抽象与多进程
注意的是:
Spring的缓存抽象没有特别处理多线程或者多进程,这些都是缓存的实现来处理的。
如果你有多进程环境(一个应用部署在多个节点上),你需要配置相应地提供你缓存的程序.根据你的用例,从多个节点上拷贝相通数据就足够了.然而,如果在应用的过程中修改了数据,则需要有其他的机制来通知修改.
缓存一个专门的对象是一个与典型的get-if-not-found-then- proceed-and-put-eventually代码块等价,是通过编程缓存交互找到.没有锁被使用,多个线程并发的获取相同的数据.删除(eviction)也同样如此.如果多个线程尝试并发的更新或者删除数据,你也许就使用了过时(stale)的数据.一些缓存提供方提供了更加高级的特性.从文档中可以看到更多的细节.
使用缓存你需要从两方面看起:
- 声明缓存:确认需要被缓存的方法还有他们使用的策略
- 配置缓存: 存储数据然后把数据读到缓存中.