SpringCache

Spring 3.1 开始  官方文档:https://docs.spring.io/spring-framework/docs/5.1.18.RELEASE/spring-framework-reference/integration.html#cache

Cache & CacheManager

SpringCache整合,简化缓存开发

  1. 引入依赖  spring-boot-starter-cache、spring-boot-starter-data-redis
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-cache -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

  2.自动配置

   CacheAutoConfiguration会导入 RedisCacheConfiguration

   自动配好了缓存管理器RedismanagerCache

  3.手动配置

spring.cache.type=redis

  4.测试使用

  @Cacheable  : 触发将数据保存到缓存的操作

  @CacheEvict : 触发将数据从缓存中删除的操作

  @CachePut :  不影响方法执行,更新缓存

  @Caching :  组合以上多个操作

  @CacheConfig :在类级别共享缓存的相同配置

  1. 开启缓存功能@Enablecaching
  2. 方法上添加@Cacheable    如果缓存中有,方法不用调用。如果缓存中没有,会调用方法,最后将方法的结果放入缓存

    【缓存的分区(按照业务类型分)】 @Cacheable("category")

   3.默认行为:

  • 如果缓存中有,方法不会调用
  • key默认自动生成,缓存的名字::Simplekey[]{自动生成key值}
  • 缓存的value值,默认使用jdk序列化机制,将序列化后的数据存到redis
  • 默认ttl时间:-1

  4.自定义行为

  • 指定生成的缓存使用的key,key属性制定,接收一个Spel
  • 指定缓存的存活时间,配置文件中修改
  • 将数据保存为json模式

  

自定义配置

spring.cache.redis.time-to-live=300000
spring.cache.type=redis

spring.cache.redis.key-prefix=CACHE_
spring.cache.redis.use-key-prefix=true
#是否缓存空值,防止缓存穿透
spring.cache.redis.cache-null-values=true
@EnableConfigurationProperties(CacheProperties.class)
@Configuration
@EnableCaching
public class MyCacheConfig {
    @Bean
    RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties){
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        //config = config.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;
    }
}

Spring Cache使用

@Cacheable  触发缓存写   (value=catagory:缓存分区,key=缓存后缀)

  @Cacheable(value = {"catagory"},key = "#root.method.name")
    @Override
    public List<CategoryEntity> getLevel1Categorys() {
        List<CategoryEntity> list = baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("parent_cid", 0));
        return list;
    }

@CacheEvict 缓存删

  /**
     * 级联更新所有关联操作
     * @CacheEvict:失效模式
     * 同时进行多种缓存操作
     * @param category
     */
//    @Caching(evict = {
//            @CacheEvict(value = "category",key = "'getLevel1Categorys'"),
//            @CacheEvict(value = "category",key = "'getCatalogJson'")
//    })

    /**
     *指定某分区(category)下的所有数据,全部删除。
     */
    @CacheEvict(value = "category",allEntries = true)
    @Transactional
    @Override
    public void updateCascade(CategoryEntity category) {

Spring-cache不足

  1、读模式

  • 缓存穿透:查询一个null数据。解决:缓存空数据;
#是否缓存空值,防止缓存穿透
spring.cache.redis.cache-null-values=true
  • 缓存击穿:大量并发进来同时查询一个正好过期的数据。(默认不加锁)解决:加锁  sync=true(加锁)
@Cacheable(value = {"catagory"},key = "#root.method.name",sync = true)
  • 缓存雪崩:大量key同时过期(超大应用存在考虑)。解决:加随机时间。加上过期时间

   2、写模式(缓存与数据库一致)

  • 读写加锁
  • 引入Cane了,感知到mysql的更新去更新数据库
  • 读多写多,直接去数据库查询

  3、原理

   使用整合redis

   CacheManager(RedisCacheManager) -> Cache(RedisCache)

总结:

  常规数据(读多写少,及时性一致性要求不高的数据);完全可以使用Spring-Cache;写模式( 只要有过期时间即可

  特殊数据:特殊设计

原文地址:https://www.cnblogs.com/sgrslimJ/p/13723571.html