SpringCache分布式缓存学习

07/02 16:30
阅读数 52

Spring Cache

简介

  • Cache接口为缓存的组件规范定义,包含缓存的各种操作集合
  • Cache接口下Spring提供了各种xxcache的实现;如RedisCache,EhCacheCache,ConcurrentMapCache等;
  • 每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否已经被调用过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓存结果后返回给用户。下次调用直接从缓存中获取。

image-20200630140504269

引入依赖

<!--引入spring cache-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>

配置

spring.cache.type=redis

开启注解

@EnableCaching

常用注解

  • @Cacheable:触发操作将数据保存到缓存中,参数value指cacheName
  • @CacheEvict:触发操作将数据从缓存中删除(运用于失效模式)
  • @CachePut:不影响方法执行更新(运用于双写模式)
  • @Caching:组合以上多个操作
  • @CacheConfig:再类级别上共享有关缓存的配置

默认配置

  • key自动生成:缓存名字::SimpleKey[]
  • value默认是jdk序列化
  • 默认ttl时间:-1
  • 默认查询数据如果缓存中存在,则不再调用方法,直接将缓存中命中的数据返回

自定义配置

  • 指定key:

    • key默认为spel表达式:#root.method.name指用方法名作为key保存在缓存中

      • @Cacheable(value="category",key="#root.methodName")

      image-20200630163456360

    • key是字符串的话额外要加单引号(默认会做表达式解析)

      • @Cacheable(value=“category”,key=“‘catalogJson-cache’”)
    • 缓存key表达为:

      • 指定前缀(前提:有指定前缀并且开启了使用前缀)+指定key名

        image-20200630154750496

      • 推荐: 默认前缀(缓存名字,前提:允许使用前缀,没有指定前缀):: key名字 (并且保存在以指定的缓存名字namespace下,树形结构显示)

        image-20200630154927208

      • key名字(前提:无前缀)

        image-20200630155220833

  • 指定其他信息

    spring.cache.type=redis
    #指定ttl,单位必需(m,s,h,d)
    spring.cache.redis.time-to-live=3600000m 
    spring.cache.redis.key-prefix=CACHE_
    spring.cache.redis.use-key-prefix=true
    #默认允许缓存空值->解决缓存穿透问题,暂时性保存null给其他并发线程返回,以保护数据库
    spring.cache.redis.cache-null-values=true 
    
  • 将value改为json格式(默认Jdk序列化器)

    Redis序列化器:

image-20200630150852638

@EnableCaching
@Configuration
public class MyCacheConfig {

    @Bean
    RedisCacheConfiguration cacheConfiguration(CacheProperties cacheProperties){
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        //entryTtl方法返回一个新的RedisCacheConfiguration对象覆盖原有对象,其他属性方法也是如此
        //cacheConfig=cacheConfig.entryTtl()
        //config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
        config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

        //整合配置文件(不整合配置文件所配置的内容不生效)
        //取出配置信息
        CacheProperties.Redis redisProperties = cacheProperties.getRedis();

        if (redisProperties.getTimeToLive() != null) {
            config = config.entryTtl(redisProperties.getTimeToLive());
        }

        if (redisProperties.getKeyPrefix() != null) {
            config = config.prefixKeysWith(redisProperties.getKeyPrefix());
        }

        if (!redisProperties.isCacheNullValues()) {
            config = config.disableCachingNullValues();
        }

        if (!redisProperties.isUseKeyPrefix()) {
            config = config.disableKeyPrefix();
        }

        return config;
    }

}

更新缓存数据

1、@CacheEvict

用于缓存失效模式:修改后删除该缓存信息

@CacheEvict 是用来标注在需要清除缓存元素的方法或类上的

  • 单个删除:

    在方法上标注(一般为保存,更新方法)

    @CacheEvict(value="category",key="'getLevel1Categories'")

    表示一旦执行该方法则会从缓存中删除对应的key

  • 批量删除:

    1. @Caching批量操作

      @Caching(evict = {
              @CacheEvict(value="category",key="'getLevel1Categories'"),
              @CacheEvict(value="category",key="'getCatalogJson'")
      })
      
    2. 删除整个namespace(一般统一类型的数据存放在同一个分区中)

      @CacheEvict(value="category",allEntries = true)

      • allEntries:默认为false,当其为true时表示清除缓存中的所有元素
      • beforeInvocation:默认是false,表示执行方法后删除(当方法如果因为抛出异常而未能成功返回时也不会触发清除操作),当指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。

2、@CachePut

用于缓存双写模式:修改后立即写入缓存

@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行方法,并将结果(方法返回值)存入指定的缓存中

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
在线直播报名
返回顶部
顶部