spring cache基础篇

Spring从3.1开始定义了org.springframework.cache.Cache和 org.springframework.cache.CacheManager接口来统一不同的缓存技术;并支持使用 JSR-107 注解简化我们开发;

提供支持多种缓存的实现。

主要接口有两个:

  1. org.springframework.cache.Cache:用于定义缓存的各种操作
  2. org.springframework.cache.CacheManager :用于管理各个cache缓存组件

常用注解:

 @Cacheable   通常用于配置方法,将方法的返回结果注入到缓存对象中(保存缓存)

                如果缓存中有,则不调用方法,如果缓存没有,才会调用方法,将结果放入缓存

@CacheEvict  可用于类或方法,用于清空缓存(删除缓存)    (失效模式使用该注解)

@CachePut :   

     强制执行方法并将返回结果放入缓存,而不是像 @Cacheable 那样首先从缓存中寻找方法返回结果是否存在缓存 (不影响方法执行更新缓存)   (双写模式使用该注解)

@Caching   组合以上多个操作

@CacheConfig   用于对类进行配置,对整个类的缓存进行配置,可用 @Cacheable取代

@EnableCaching  用于SpringBoot的启动类,开启注解功能

使用: 

<dependency>
    <groupId>org.springframework.b oot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
spring:
  cache:
  	#指定缓存类型为redis
    type: redis
    redis:
      # 指定redis中的过期时间为1h
      time-to-live: 3600000

默认行为:

   》如果缓存中有,方法不会被调用

   》 key默认自动生成:缓存的名字:SimpleKey

   》缓存的value值,默认使用jdk序列化机制,将序列化后的数据存到redis

   》默认ttl时间:-1,也就是永不过期

自定义:

   >指定生成的缓存的key   使用注解里面的属性key来指定 key=" 'xxx' " 需要加上单引号,

           否则会认为是一个表达式,还有一个value是配置key的分区,(在spring中,redis没有)

   >缓存的value保存为json格式

   >设置key的过期时间  :上面的配置文件中已经配置了

配置value的json格式

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

    //方法参数会通过注入的方式传入,当然我们也可以使用变量的方式写来注入
    @Bean
    public RedisCacheConfiguration redisCacheConfiguration( CacheProperties cacheProperties) {
        
        CacheProperties.Redis redisProperties = cacheProperties.getRedis();
        org.springframework.data.redis.cache.RedisCacheConfiguration config = org.springframework.data.redis.cache.RedisCacheConfiguration
            .defaultCacheConfig();
        //指定缓存序列化方式为json
        config = config.serializeValuesWith(
            RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));


        //下面的这四个配置,如果我们不写在这里的话,将读取不到。默认的配置也会有的,但是我们自己写配置类的话,就需要加上去,

        //设置配置文件中的各项配置,如过期时间
        if (redisProperties.getTimeToLive() != null) {
            config = config.entryTtl(redisProperties.getTimeToLive());
        }
        
         //key的前缀
        if (redisProperties.getKeyPrefix() != null) {
            config = config.prefixKeysWith(redisProperties.getKeyPrefix());
        }

        //是否缓存空值
        if (!redisProperties.isCacheNullValues()) {
            config = config.disableCachingNullValues();
        }

         //是否使用key的前缀
        if (!redisProperties.isUseKeyPrefix()) {
            config = config.disableKeyPrefix();
        }
        return config;
    }
}


//注意,通过源码发现,自己配置类的话,需要将配置文件的配置在这里进行配置,否则不会生效,比如过期时间,前缀等。


当然配置了这些,配置文件里面肯定是不可少的

spring.cache.redis.cache-null-values=true
spring.cache.redis.key-prefix=xxx
spring.cache.redis.use-key-prefix=true
在加上上面的配置的过期时间。

还有就是要注意的是,
之前我们说了@Cacheable()注解,他的value是配置的key的分区名称,
如果我们在配置文件spring.cache.redis.key-prefix里面配置的前缀会覆盖注解里配置的分区。
如果spring.cache.redis.use-key-prefix为false的话,则两边的配置前缀都不会生效,也就是没有前缀


建议:
   同一类型的数据使用相同的1分区名,方便删除更新
   在配置文件中不设置前缀,同一使用注解的value分区名称作为前缀

那么spring cache如何解决缓存穿透,缓存击穿,缓存雪崩

其中,缓存穿透我们在配置文件中,设置了可以缓存null值,所以就相当于解决了

缓存雪崩的话,由于在配置文件中加了key的过期时间,由于程序的时间线不一样,统一的过期时间设置能达到kry的不同失效时间,

而缓存击穿的话,就是在@Cacheable(sync=true)该注解上加上该属性,就可以了,

其内部就是一个本地的一个synchroized锁,判断没有值,则开一个线程任务去数据库获取值,然后将值设置进缓存中返回。

写模式:写多读多,或者写多读少,建议直接·使用数据库,不使用缓存,

或者使用canal

上一篇:开发中常用命令汇总


下一篇:关于node.js的下载安装和环境变量的配置(超详细)