Spring Boot之缓存

本文深入探讨了Spring Boot的缓存机制,包括JSR-107、Spring缓存抽象和Redis整合。详细介绍了@Cacheable、@CachePut、@CacheEvict等注解的使用,并解析了缓存的工作原理及Redis缓存的配置和操作。
摘要由CSDN通过智能技术生成

一、Spring Boot之缓存

SpringBoot中,可以使用以下三种缓存方式:

  1. JSR-107
  2. Spring缓存抽象
  3. 整合Redis

1、JSR-107

Java Caching定义了5个核心接口,分别是CachingProvider, CacheManager, Cache, EntryExpiry

  • CachingProvider定义了创建、配置、获取、管理和控制多个CacheManager。一个应用可 以在运行期访问多个CachingProvider。
  • CacheManager定义了创建、配置、获取、管理和控制多个唯一命名的Cache,这些Cache 存在于CacheManager的上下文中。一个CacheManager仅被一个CachingProvider所拥有。
  • Cache是一个类似Map的数据结构并临时存储以Key为索引的值。一个Cache仅被一个 CacheManager所拥有。
  • Entry是一个存储在Cache中的key-value对。
  • Expiry 每一个存储在Cache中的条目有一个定义的有效期。一旦超过这个时间,条目为过期 的状态。一旦过期,条目将不可访问、更新和删除。缓存有效期可以通过ExpiryPolicy设置。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-imwH6uQc-1598323780176)(IMAGES/Snipaste_2020-08-04_20-52-35.png)]

2、Spring缓存抽象

Spring从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口来统一不同的缓存技术; 并支持使用JCache(JSR-107)注解简化我们开发;

  • Cache接口为缓存的组件规范定义,包含缓存的各种操作集合;
  • Cache接口下Spring提供了各种xxxCache的实现;如RedisCache,EhCacheCache , ConcurrentMapCache等;
  • 每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否 已经被调用过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法 并缓存结果后返回给用户。下次调用直接从缓存中获取。
  • 使用Spring缓存抽象时我们需要关注以下两点;
    • 确定方法需要被缓存以及他们的缓存策略
    • 从缓存中读取之前缓存存储的数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jntviggK-1598323780182)(IMAGES/Snipaste_2020-08-04_20-55-04.png)]

3、几个重要概念&缓存注解

作用
Cache 缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、 ConcurrentMapCache等
CacheManager 缓存管理器,管理各种缓存(Cache)组件
@Cacheable 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
@CacheEvict 清空缓存
@CachePut 保证方法被调用,又希望结果被缓存。
@EnableCaching 开启基于注解的缓存
keyGenerator 缓存数据时key生成策略
serialize 缓存数据时value序列化策略

@Cacheable/@CachePut/@CacheEvict 主要的参数

作用 例子
value 缓存的名称,在 spring 配置文件中定义,必须指定 至少一个 例如:
@Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达 式编写,如果不指定,则缺省按照方法的所有参数 进行组合 例如:
@Cacheable(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存/清除缓存,在 调用方法之前之后都能判断 例如:
@Cacheable(value=”testcache”,condition=”#userNam e.length()>2”)
allEntries (@CacheEvict )
是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 例如:
@CachEvict(value=”testcache”,allEntries=true)
beforeInvocation (@CacheEvict) 是否在方法执行前就清空,缺省为 false,如果指定 为 true,则在方法还没有执行的时候就清空缓存, 缺省情况下,如果方法执行抛出异常,则不会清空 缓存 例如:
@CachEvict(value=”testcache”, beforeInvocation=true)
unless (@CachePut) (@Cacheable) 用于否决缓存的,不像condition,该表达式只在方 法执行之后判断,此时可以拿到返回值result进行判 断。条件为true不会缓存,fasle才缓存 例如: @Cacheable(value=”testcache”,unless=”#result == null”)

Cache SpEL available metadata

名字 位置 描述 示例
methodName root object 当前被调用的方法名 #root.methodName
method root object 当前被调用的方法 #root.method.name
target root object 当前被调用的目标对象 #root.target
targetClass root object 当前被调用的目标对象类 #root.targetClass
args root object 当前被调用的方法的参数列表 #root.args[0]
caches root object 当前方法调用使用的缓存列表(如@Cacheable(value={“cache1”, “cache2”})),则有两个cache #root.caches[0].name
argument name evaluation context 方法参数的名字. 可以直接 #参数名 ,也可以使用 #p0或#a0 的 形式,0代表参数的索引; #iban 、 #a0 、 #p0
result evaluation context 方法执行后的返回值(仅当方法执行之后的判断有效,如 ‘unless’,’cache put’的表达式 ’cache evict’的表达式 beforeInvocation=false) #result

4、缓存使用

1. 搭建基本环境(MyBatis)

  1. 导入数据库文件 创建出department和employee表
  2. 创建javaBean封装数据
  3. 整合MyBatis操作数据库
    1. 配置数据源信息
    2. 使用注解版的MyBatis;
      • @MapperScan指定需要扫描的mapper接口所在的包

在配置文件中配置日志级别为debug

#若向数据库执行语句,会输出sql执行的debug信息
#若在缓存中查询则不会,用来判断是否走了缓存
logging.level.包名=debug
# 示例:logging.level.com.atguigu.cache.mapper=debug

#开启自动配置类报告
debug=true

2. 缓存使用

步骤:

  1. 导入依赖spring-boot-starter-cache
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
  1. 开启基于注解的缓存 @EnableCaching

  2. 标注缓存注解即可

  • @Cacheable
  • @CacheEvict
  • @CachePut

默认使用的是ConcurrentMapCacheManager==ConcurrentMapCache;将数据保存在ConcurrentMap<Object, Object>中

开发中使用缓存中间件;redis、memcached、ehcache;

@MapperScan("com.atguigu.cache.mapper")          //扫描mapper接口所在包
@SpringBootApplication
@EnableCaching             //开启基于注解的缓存
public class Springboot01CacheApplication {
   

   public static void main(String[] args) {
   
      SpringApplication.run(Springboot01CacheApplication.class, args);
   }
}

3. @Cacheable

  1. 将方法的运行结果进行缓存;以后再要相同的数据,直接从缓存中获取,不用调用方法;
    CacheManager管理多个Cache组件的,对缓存的真正CRUD操作在Cache组件中,每一个缓存组件有自己唯一一个名字;

  2. 几个属性:

    • cacheNames/value:指定缓存组件的名字;将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存;

    • key:缓存数据使用的key;可以用它来指定。

      • 假设传入id = 1,则 key:1, value:方法的返回值

      • 编写SpEL; #id;参数id的值,也可以写成:#a0 #p0 #root.args[0]

        @Cacheable(value = {
                 "emp"},key="#root.methodName+'['+#id+']'")
        
        //该SpEL表达式指定生成key的形式 ===> getEmp[2] (id=2的时候)
        

        (参考上面的Cache SpEL available metadata表格)

    • keyGenerator:key的生成器;可以自己指定key的生成器的组件id
      key/keyGenerator:二选一使用;

    自定义keyGenerator:

    //自定义
    @Configuration
    public class MyCacheConfig {
         
    
        @Bean("myKeyGenerator")
        public KeyGenerator keyGenerator(){
         </
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值