为什么使用?

写缓存逻辑太麻烦了,是用SpringCache缓存框架,方便的注解

引入

  1. <!--springCache-->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-cache</artifactId>
  5. </dependency>

注解

  1. @Cacheable 当前方法的结果需要缓存,如果缓存中有直接返回,没有则调用方法再放入缓存,需要指定缓存的分区
  2. @Cacheable (value = {"category"})
  3. @CacheEvict ---触发将数据从缓存中删除的方法 失效模式
  4. @CachePut ---不影响方法执行更新缓存 双写模式
  5. @Caching ---组合以上多个操作
  6. @CacheConfig ---在类级别共享缓存的相同配置

1.开启缓存

  1. @EnableCaching
  2. spring.cache.type=redis #properties配置文件中配置

2.可以使用自定义的配置

  1. @EnableConfigurationProperties(CacheProperties.class) //开启属性配置的绑定功能
  2. @Configuration
  3. @EnableCaching //开启缓存
  4. public class myCacheConfig {
  5. @Bean
  6. public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
  7. RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
  8. //修改序列化方式
  9. config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
  10. config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
  11. CacheProperties.Redis redisProperties = cacheProperties.getRedis();
  12. //将配置文件中的属性值生效
  13. if (redisProperties.getTimeToLive() != null) {
  14. config = config.entryTtl(redisProperties.getTimeToLive());
  15. }
  16. if (redisProperties.getKeyPrefix() != null) {
  17. config = config.prefixKeysWith(redisProperties.getKeyPrefix());
  18. }
  19. if (!redisProperties.isCacheNullValues()) {
  20. config = config.disableCachingNullValues();
  21. }
  22. if (!redisProperties.isUseKeyPrefix()) {
  23. config = config.disableKeyPrefix();
  24. }
  25. return config;
  26. }
  27. }

yml配置文件

  1. #缓存类型
  2. spring.cache.type=redis
  3. #key的存活时间
  4. spring.cache.redis.time-to-live=3600000
  5. #key默认前缀,默认前缀是分区名
  6. #spring.cache.redis.key-prefix=CACHE_
  7. #是否开始使用key默认前缀
  8. spring.cache.redis.use-key-prefix=true
  9. #是否缓存空值
  10. spring.cache.redis.cache-null-values=true

3.使用注解

  1. //@CacheEvict(value = {"category"}, key = "'getLevelOneCategory'") //失效模式--改完删除缓存,保证数据一致性
  2. //组合多个操作
  3. /*@Caching(evict = {
  4. @CacheEvict(value = {"category"}, key = "'getLevelOneCategory'"),
  5. @CacheEvict(value = {"category"}, key = "'getCatalgJson'")
  6. })*/
  7. //删除某个缓存分区中的所有数据
  8. @CacheEvict(value = "category",allEntries = true)
  1. @Cacheable(value = {"category"}, key = "#root.method.name")

如何加锁解决缓存击穿?

  1. @Cacheable(value = {"category"}, key = "#root.method.name",sync = true)

sync表示加锁(本地),其他注解中没有sync属性
写模式需要自己进行加锁,如读写锁等根据不同情况
总结:对数据即时性,一致性要求不高,读多写少使用springcache没有问题
对于某些特殊数据需求自己进行特殊的缓存和加锁的设计