整天都在讨论使用SpringBoot,可你居然连缓存都不清楚
缓存技术是一个让所有开发人员又爱又恨的技术,我们爱缓存是因为缓存能给我们带来数量级的响应和流量,但是最迷人的反而最危险,如果缓存用不好也是灾难级别的,特别是一些涉及到公司主要现金流的业务,如果因为我们使用缓存不当,而带给公司一定的损失,不亚于删库跑路的那个大兄弟,那今天我们就来看一下springboot的缓存都有那些东西,学习嘛,一点点的来,慢慢积累自己的经验,才能厚积薄发
个人公众号:Java架构师联盟,每日更新技术好文
一、JSR107缓存规范
为了缓存开发规范的统一,以及提升系统的扩展性,J2EE发布了JSR107缓存规范。 主要是Java Caching定义了5个接口,分别是CachingProvider、CacheManager、Cache、Entry、Expiry。
下面我们分开详细的展开看一下
-
CachingProvider:
-
可以创建、配置、获取、管理和控制多个CacheManager,一个Application在运行期间可以访问多个CachingProvider。
-
CacheManager:
-
可以创建、配置、获取、管理和控制多个唯一命名的Cache,这些Cache存在于CacheManager的上下文中。一个CacheManager仅被一个CachingProvider所拥有。
-
Cache:
-
是一个类似于Map的数据结构并临时存储以Key为索引的值。一个Cache仅被一个CacheManager所拥有。
-
Entry:
-
是存储在Cache中的Key-Value对。
-
Expiry:
-
每一个缓存在Cache中的条目有一个定义的有效期,一旦超过这个时间,该条目就为过期状态,一旦过期,条目将不可访问、更新和删除。其中缓存的有效期可以通过ExpiryPolicy设置。
-
如果说这样讲解让你有点蒙圈的话,那没关系,我们看下面这张图
简单总结一下就是:一个应用里面可以有多个缓存提供者(CachingProvider),一个缓存提供者可以获取到多个缓存管理器(CacheManager),一个缓存管理器管理着不同的缓存(Cache),缓存中是一个个的缓存键值对(Entry),每个entry都有一个有效期(Expiry)。缓存管理器和缓存之间的关系有点类似于数据库中连接池和连接的关系。
二、SpringBoot缓存抽象
在我自己看来,没有源码所有的理论讲解,都是空谈,或者说就是扯淡,所以我们来看一下,缓存的源码级操作
Spring从3.1版本开始定义了org.springframework.cache.CacheManager和org.springframework.cache.Cache接口来统一不同的缓存技术,并支持使用JSR-107注解简化开发。 在IDEA中,使用Spring Initializr快速创建Spring Boot项目时,勾选中Cache后,在配置文件中配置debug=true,可以查看Spring Boot的自动配置项。 其中关于缓存的配置类如下:
org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration org.springframework.boot.autoconfigure.cache.JCacheCacheConfiguration org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration org.springframework.boot.autoconfigure.cache.HazelcastCacheConfiguration org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration org.springframework.boot.autoconfigure.cache.CouchbaseCacheConfiguration org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration org.springframework.boot.autoconfigure.cache.CaffeineCacheConfiguration org.springframework.boot.autoconfigure.cache.GuavaCacheConfiguration org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration
启动项目后,可以在控制台看到匹配到的只有SimpleCacheConfiguration这个自动配置类,而在SimpleCacheConfiguration类中,使用@Bean注解给容器中注册了一个CacheManager,由此可看Spring Boot默认的CacheManager是ConcurrentMapCacheManager。
SimpleCacheConfiguration matched: - Cache org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration automatic cache type (CacheCondition) - @ConditionalOnMissingBean (types: org.springframework.cache.CacheManager; SearchStrategy: all) did not find any beans (OnBeanCondition)
同样的,我们通过一张图形象的展示一下看看
几个重要概念和缓存注解:
进入@Caching的源码可以看到,在组合注解内可以使用cacheable、put、evict
public @interface Caching { Cacheable[] cacheable() default {}; CachePut[] put() default {}; CacheEvict[] evict() default {}; }
@Caching的使用
@Caching( cacheable = { @Cacheable(key = "#name") }, put = { @CachePut(key = "#result.id"), @CachePut(key = "#result.cNo") } )
@Cacheable、@CachePut、@CacheEvict中的主要参数
key
#缓存的key,可以为空,也可以使用SpEL表达式编写 例:@Cacheable(value=“stu”,key=“userName”)
condition
#缓存的条件,可以为空,也可以使用SpEL表达式编写,只有为true才缓存/清除缓存, #不管方法执行前后都可以判断 例:@Cacheable(value=“stu”,condition=“userName.length()>2”)
unless
#用于否定缓存,只在方法执行之后判断,也可以使用SpEL表达式编写 #true不缓存,false才缓存 例:@Cacheable(value=“stu”,unless=“userName == null”)
-
@Cacheable
-
标注的方法执行之前,先查看缓存中有没有这个数据,默认按照参数的值作为key去缓存中查找。如果没有就运行这个方法并将方法的执行结果放入缓存中,之后再调用该方法时,直接使用缓存中的数据即可。
-
@CachePut
-
标注的方法必须要执行,它的运行时机是,先调用目标方法,然后将目标方法的结果放入缓存中,但是更新缓存中的数据时,要注意key值,否则缓存中的数据无法更新。
-
@CacheEvict
-
这个注解中allEntries = true代表要清除某个缓存中的所有数据。beforeInvocation = false代表缓存的清除在方法执行之后执行,如果出现异常等情况,则不会清除缓存中的数据。这是@CacheEvict
-
注解默认的。beforeInvocation = true代表缓存的清除在方法执行之前执行,出现异常等情况,也会清除缓存中的数据。
-
key的生成策略
-
key的生成默认使用SimpleKeyGenerator生成的,而SimpleKeyGenerator的生成策略有:如果没有参数:key=new SimpleKey();如果有一个参数:key=参数的值如果有多个参数:key=new SimpleKey(params);

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
开始切换到 Kotlin: 谷歌工程师给初学者的知识点总结
在 2019 年的 I/O 大会上,我们曾宣布 Kotlin 将会是 Android 应用开发的首选语言,但是,部分开发者们反馈仍不清楚如何切换到 Kotlin,如果团队中没有人熟悉 Kotlin,一开始直接使用 Kotlin 进行项目开发还是会令人生畏。 在 Android Studio Profiler 团队内部,我们是通过几个步骤克服了这个问题,第一步是要求所有的单元测试使用 Kotlin 编写。这么做有效避免了我们犯的任何微小错误直接影响到生产环境中的代码,因为单元测试与生产环境的代码是分开的。 我收集了我们团队在历次 Code Review 中遇到过的常见问题并整理出了这篇文章,希望这篇文章对广大 Android 社区的朋友们有所帮助。 注意: 本文的目标读者是 Kotlin 的初学者,如果您的团队已经熟练使用 Kotlin 进行项目开发,本文对您的帮助可能不大。但如果您觉得我们遗漏了一些应该被提及的内容,请在本文留言区留言告诉我们。 IDE 功能: 把 Java 文件转换成 Kotlin 文件 如果您使用 Android Studio 开发程序,学习 Kotlin 的最简单...
- 下一篇
Redis深度系统学习之RDB与AOF持久化
前言 在上一篇文章中,介绍了Redis的内存模型,从这篇文章开始,将依次介绍Redis高可用相关的知识——持久化、复制(及读写分离)、哨兵、以及集群。 本文将先说明上述几种技术分别解决了Redis高可用的什么问题;然后详细介绍Redis的持久化技术,主要是RDB和AOF两种持久化方案;在介绍RDB和AOF方案时,不仅介绍其作用及操作方法,同时介绍持久化实现的一些原理细节及需要注意的问题。最后,介绍在实际使用中,持久化方案的选择,以及经常遇到的问题等。 目录 一、Redis高可用概述 二、Redis持久化概述 三、RDB持久化 1. 触发条件 2. 执行流程 3. RDB文件 4. 启动时加载 5.RDB常用配置总结 四、AOF持久化 1. 开启AOF 2. 执行流程 3. 启动时加载 4.AOF常用配置总结 五、方案选择与常见问题 1.RDB和AOF的优缺点 2. 持久化策略选择 3.fork阻塞:CPU的阻塞 4.AOF追加阻塞:硬盘的阻塞 5.info命令与持久化 六、总结 一、Redis高可用概述 在介绍Redis高可用之前,先说明一下在Redis的语境中高可用的含义。 我们知道...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS8安装Docker,最新的服务器搭配容器使用
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装