引入依赖

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- springboot starter默认已经引入-->
<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-autoconfigure</artifactId>
</dependency>

配置文件

更改application.yml文件如下。这里的type除了用redis,还支持caffeine/jcache/couchbase/ehcache/infinispan/simple(内存缓存) 等类型。需要引入对应依赖。

  • time-to-live 缓存过期时间ttl,可以用1h,30m等形式表示。

    注意spring的cache默认是统一过期时间,没法为每个cache单独设置过期时间,如有这种需求需要自己另行封装

  • key-prefix 统一key前缀,默认为空

  • uses-key-prefix redis缓存的key是否使用前缀,默认是true。
    需注意,即使上面的key-prefix设为空,在使用@Cacheable等注解时,会将value/cacheName当做key的前缀,实际的key为cacheName + key,需要自己视情况更改配置

  • cache-null-values 是否缓存空值,默认为true。如关闭的话需注意缓存穿透问题

  • 其它各种类型缓存的配置均可在org.springframework.boot.autoconfigure.cache.CacheProperties中找到。

spring:
  cache:
    type: redis
    redis:
      time-to-live: 1h  #过期时间
      use-key-prefix: false  #默认为true
      # cache-null-values: true # 默认true

最小化实例

  1. 在完成以上配置的基础上,在springboot的App启动类上加上注解 @EnableCaching(proxyTargetClass = true)

@EnableCaching(proxyTargetClass = true)
@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class,args);
    }
}
  1. 自定义缓存方法。以用户类User为例自定义UserRepository来对用户信息进行缓存。

    • @Cacheable表示该方法使用缓存,value为整个缓存的名称cacheName

    • key为查询缓存的key,可使用spel表达式,在这里为方法的参数userId。也可以使用keyGenerator来指定生成key的bean

    • condition为条件表达式。在调用方法前执行,决定是否使用缓存,默认是"",表示结果始终使用缓存

    • unless为条件表达式,与condition不同的是此表达式是在调用方法之后求值,因此可以引用结果,默认值是"",表示缓存结果永远不会被否决。这里是结果不为空时才缓存(可能存在缓存穿透,此处只是示例)

public class User {
    private Long id;
    private String name;
    //... getter and setter
}
@Component
public class UserRepository {

    @Cacheable(value = "userCache",key = "#userId",condition = "#enableCache == true", unless = "#result == null")
    public User getUser(Long userId, boolean enableCache) {
        //... get userfrom data base
    }
}

更改序列化配置

到上一步为止已经可以正常的从缓存获取配置了。但实际上我们没有对缓存进行任何配置,全部使用的默认配置。而Redis Cache默认使用的value序列化方式是JDK序列化,我们一般会改成json序列化,所以这里需要新加一个配置。

@Configuration
public class RedisConfig {
   @Bean
    public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
        CacheProperties.Redis redisProperties = cacheProperties.getRedis();
        RedisCacheConfiguration config = RedisCacheConfiguration
                .defaultCacheConfig();
        config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
        if (redisProperties.getTimeToLive() != null) {
            config = config.entryTtl(redisProperties.getTimeToLive());
        }
        if (redisProperties.getKeyPrefix() != null) {
            config = config.prefixCacheNameWith(redisProperties.getKeyPrefix());
        }
        if (!redisProperties.isCacheNullValues()) {
            config = config.disableCachingNullValues();
        }
        if (!redisProperties.isUseKeyPrefix()) {
            config = config.disableKeyPrefix();
        }
        return config;
    }
}