当前位置: 首页> 健康> 养生 > 谷粒商城实战笔记-170~172-缓存-SpringCache

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

时间:2025/9/17 18:05:48来源:https://blog.csdn.net/epitomizelu/article/details/141116949 浏览次数:0次

文章目录

  • 一,170-缓存-SpringCache-自定义缓存配置
  • 二,171-缓存-SpringCache-@CacheEvict
    • 1,删除多个缓存
    • 2,删除一个缓存
  • 三,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));}

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

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

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

@EnableConfigurationProperties(CacheProperties.class)
@Configuration
@EnableCaching
public class MyCacheConfig {// @Autowired// public CacheProperties cacheProperties;@Beanpublic 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;}}

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

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

@EnableConfigurationProperties 的作用

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

使用 CacheProperties 的两种方式

  1. 自动注入 (@Autowired):

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

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

二,171-缓存-SpringCache-@CacheEvict

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

1,删除多个缓存

@Caching( evict = {@CacheEvict(value = {"category"}, key = "'getLevel1Categorys'"),@CacheEvict(value = {"category"}, key = "'catelogJson'")})

在这里插入图片描述

2,删除一个缓存

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

在这里插入图片描述

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

对Redis缓存的三个问题:

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

SpringCache提供相应的解决方案:

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

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

关键字:谷粒商城实战笔记-170~172-缓存-SpringCache

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: