当前位置:   article > 正文

谷粒商城实战笔记-170~172-缓存-SpringCache

谷粒商城实战笔记-170~172-缓存-SpringCache

一,170-缓存-SpringCache-自定义缓存配置

上一节我们提到,@Cacheable的默认行为包括:

  • ① key是默认生成的:缓存的名字::SimpleKey::
  • ② 缓存的value值,默认使用jdk序列化机制,将序列化的数据存到redis中
  • ③ 默认时间是 -1,即永不过期

①可以通过@Cacheable注解的属性key自定义。

③可以通过配置文件设置过期时间。

本节将介绍如何修改key、value的序列化机制。

根据SpringBoot的原理,一定有一个类用来封装配置文件中的配置,Spring Cache的这个配置自动装配类是CacheAutoConfiguration,看这个类的源码,其加载了Redis的配置类RedisCacheConfiguration,这个类中使用了Spring Cache的配置创建RedisCacheManger类,这个类中实现了对Redis的读写操作。

根据源码可以看出,如果容器中有redisCacheConfiguration对象,就使用容器中的对象,否则就创建一个。

	private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration(
			CacheProperties cacheProperties,
			ObjectProvider<org.springframework.data.redis.cache.RedisCacheConfiguration> redisCacheConfiguration,
			ClassLoader classLoader) {
		return redisCacheConfiguration.getIfAvailable(() -> createConfiguration(cacheProperties, classLoader));
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

默认是没有向容器中注入redisCacheConfiguration对象的,会创建一个,但是创建的对象中没有设置key和value的序列化器,会用默认的JDK序列化器。

所以,我们可以向容器中注入一个redisCacheConfiguration对象,在这个对象中设置JSON序列化器,在创建RedisCacheManger对象时,就会使用我们注入的对象,redis就会使用我们配置的json序列化。

所以,我们可以自定义一个配置类,向容器中注入redisCacheConfiguration对象,在创建这个对象时设置序列化方式。




@EnableConfigurationProperties(CacheProperties.class)
@Configuration
@EnableCaching
public class MyCacheConfig {

    // @Autowired
    // public CacheProperties cacheProperties;


    @Bean
    public 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;
    }

}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

在这段代码中,创建并向容器中注入了一个RedisCacheConfiguration对象。

这里需要注意,需要通过@EnableConfigurationProperties激活CacheProperties读取和封装配置文件中的配置。

@EnableConfigurationProperties 的作用

  • 激活自动绑定@EnableConfigurationProperties 注解告诉Spring框架去查找并激活一个或多个由 @ConfigurationProperties 标记的类,这些类可以用来绑定配置文件中的属性值。
  • 注册绑定类:它会将标记为 @ConfigurationProperties 的类注册为一个配置类,这样就可以直接在Spring容器中注入这些配置类的实例,并且它们会自动绑定到配置文件中的属性。

使用 CacheProperties 的两种方式

  1. 自动注入 (@Autowired):

    • 作用:使用 @Autowired 注入 CacheProperties 类的实例,这种方式可以直接在类的字段上使用,不需要额外的方法调用。
    • 示例
      @Autowired
      private CacheProperties cacheProperties;
      
      • 1
      • 2
  2. 作为方法参数

    • 作用:将 CacheProperties 作为方法参数传递,这种方式通常用于方法内部需要使用配置属性的情况。
    • 示例
      @Bean
      public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
          // ...
      }
      
      • 1
      • 2
      • 3
      • 4

二,171-缓存-SpringCache-@CacheEvict

Redis缓存保证最终一致性的失效模式,是在更新数据后将缓存中的数据删除,删除缓存数据可以通过@CacheEvict完成,结合@Caching可以删除多个缓存。

1,删除多个缓存

@Caching( evict = {
            @CacheEvict(value = {"category"}, key = "'getLevel1Categorys'"),
            @CacheEvict(value = {"category"}, key = "'catelogJson'")
        }
    )
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

2,删除一个缓存

@CacheEvict(value = {"category"}, key = "'getLevel1Categorys'")
  • 1

在这里插入图片描述

三,172-缓存-SpringCache-原理与不足

对Redis缓存的三个问题:

  • 缓存穿透
  • 缓存击穿
  • 缓存雪崩

SpringCache提供相应的解决方案:

  • 针对缓存穿透,可以设置控制缓存Spring.cache.redis.cache-null-values=true
  • 针对缓存雪崩,可以设置不同的过期时间来防止雪崩
  • 针对缓存击穿,Spring Cache提供了get方法的本地锁方案,没有分布式锁方案

所以,如果实时性要求高、数据一致性要求高,就不能使用Spring Cache,必须自己编写缓存相关的逻辑来实现分布式锁的方案。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/991543?site
推荐阅读
相关标签
  

闽ICP备14008679号