互联网科技

整天都在讨论使用SpringBoot,可你居然连缓存都不清楚

2020-12-05  本文已影响0人  java架构师联盟

缓存技术是一个让所有开发人员又爱又恨的技术,我们爱缓存是因为缓存能给我们带来数量级的响应和流量,但是最迷人的反而最危险,如果缓存用不好也是灾难级别的,特别是一些涉及到公司主要现金流的业务,如果因为我们使用缓存不当,而带给公司一定的损失,不亚于删库跑路的那个大兄弟,那今天我们就来看一下springboot的缓存都有那些东西,学习嘛,一点点的来,慢慢积累自己的经验,才能厚积薄发

个人公众号:Java架构师联盟,每日更新技术好文

一、JSR107缓存规范

为了缓存开发规范的统一,以及提升系统的扩展性,J2EE发布了JSR107缓存规范。 主要是Java Caching定义了5个接口,分别是CachingProvider、CacheManager、Cache、Entry、Expiry。

下面我们分开详细的展开看一下

整天都在讨论使用SpringBoot,可你居然连缓存都不清楚

简单总结一下就是:一个应用里面可以有多个缓存提供者(CachingProvider),一个缓存提供者可以获取到多个缓存管理器(CacheManager),一个缓存管理器管理着不同的缓存(Cache),缓存中是一个个的缓存键值对(Entry),每个entry都有一个有效期(Expiry)。缓存管理器和缓存之间的关系有点类似于数据库中连接池和连接的关系。

二、SpringBoot缓存抽象

在我自己看来,没有源码所有的理论讲解,都是空谈,或者说就是扯淡,所以我们来看一下,缓存的源码级操作

Spring从3.1版本开始定义了org.springframework.cache.CacheManagerorg.springframework.cache.Cache接口来统一不同的缓存技术,并支持使用JSR-107注解简化开发。 在IDEA中,使用Spring Initializr快速创建Spring Boot项目时,勾选中Cache后,在配置文件中配置debug=true,可以查看Spring Boot的自动配置项。 其中关于缓存的配置类如下:

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n6041" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(119, 119, 119); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">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</pre>

启动项目后,可以在控制台看到匹配到的只有SimpleCacheConfiguration这个自动配置类,而在SimpleCacheConfiguration类中,使用@Bean注解给容器中注册了一个CacheManager,由此可看Spring Boot默认的CacheManager是ConcurrentMapCacheManager。

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n6043" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(119, 119, 119); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> SimpleCacheConfiguration matched:

同样的,我们通过一张图形象的展示一下看看

整天都在讨论使用SpringBoot,可你居然连缓存都不清楚

几个重要概念和缓存注解:

整天都在讨论使用SpringBoot,可你居然连缓存都不清楚

进入@Caching的源码可以看到,在组合注解内可以使用cacheable、put、evict

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n6051" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(119, 119, 119); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public @interface Caching {
Cacheable[] cacheable() default {};

CachePut[] put() default {};

CacheEvict[] evict() default {};
}</pre>

@Caching的使用

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n6053" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(119, 119, 119); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> @Caching(
cacheable = {
@Cacheable(key = "#name")
},
put = {
@CachePut(key = "#result.id"),
@CachePut(key = "#result.cNo")
}
)</pre>

@Cacheable、@CachePut、@CacheEvict中的主要参数

key

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n6056" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(119, 119, 119); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">#缓存的key,可以为空,也可以使用SpEL表达式编写
例:@Cacheable(value=“stu”,key=“userName”)</pre>

condition

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n6058" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(119, 119, 119); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">#缓存的条件,可以为空,也可以使用SpEL表达式编写,只有为true才缓存/清除缓存,

不管方法执行前后都可以判断

例:@Cacheable(value=“stu”,condition=“userName.length()>2”)</pre>

unless

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n6060" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(119, 119, 119); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">#用于否定缓存,只在方法执行之后判断,也可以使用SpEL表达式编写

true不缓存,false才缓存

例:@Cacheable(value=“stu”,unless=“userName == null”)</pre>

上一篇下一篇

猜你喜欢

热点阅读