缓存技术是一个让全部开发人员又爱又恨的技术,咱们爱缓存是由于缓存能给咱们带来数量级的响应和流量,可是最迷人的反而最危险,若是缓存用很差也是灾难级别的,特别是一些涉及到公司主要现金流的业务,若是由于咱们使用缓存不当,而带给公司必定的损失,不亚于删库跑路的那个大兄弟,那今天咱们就来看一下springboot的缓存都有那些东西,学习嘛,一点点的来,慢慢积累本身的经验,才能厚积薄发spring
我的公众号:Java架构师联盟,每日更新技术好文数据库
# 1、JSR107缓存规范缓存
为了缓存开发规范的统一,以及提高系统的扩展性,J2EE发布了JSR107缓存规范。
主要是Java Caching定义了5个接口,分别是**CachingProvider、CacheManager、Cache、Entry、Expiry。**springboot
下面咱们分开详细的展开看一下数据结构
- **CachingProvider:**
- 能够建立、配置、获取、管理和控制多个CacheManager,一个Application在运行期间能够访问多个CachingProvider。
- **CacheManager:**
- 能够建立、配置、获取、管理和控制多个惟一命名的Cache,这些Cache存在于CacheManager的上下文中。一个CacheManager仅被一个CachingProvider所拥有。
- **Cache:**
- 是一个相似于Map的数据结构并临时存储以Key为索引的值。一个Cache仅被一个CacheManager所拥有。
- **Entry:**
- 是存储在Cache中的Key-Value对。
- **Expiry:**
- 每个缓存在Cache中的条目有一个定义的有效期,一旦超过这个时间,该条目就为过时状态,一旦过时,条目将不可访问、更新和删除。其中缓存的有效期能够经过ExpiryPolicy设置。
-
若是说这样讲解让你有点蒙圈的话,那不要紧,咱们看下面这张图架构
less
简单总结一下就是:一个应用里面能够有多个缓存提供者(CachingProvider),一个缓存提供者能够获取到多个缓存管理器(CacheManager),一个缓存管理器管理着不一样的缓存(Cache),缓存中是一个个的缓存键值对(Entry),每一个entry都有一个有效期(Expiry)。缓存管理器和缓存之间的关系有点相似于数据库中链接池和链接的关系。ide
# 2、SpringBoot缓存抽象学习
在我本身看来,没有源码全部的理论讲解,都是空谈,或者说就是扯淡,因此咱们来看一下,缓存的源码级操做spa
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);