SpringBoot中redis缓存的配置及使用

springboot在缓存中对多种缓存提供了支持,一下是他支持的缓存类型:

  • Generic
  • JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
  • EhCache 2.x
  • Hazelcast
  • Infinispan
  • Couchbase
  • Redis
  • Caffeine
  • Simple

本文将使用redis来对springboot在缓存上的配置及使用做简单介绍。:springboot 1.x版本和springboot 2.x版本在redis的缓存配置上存在些许不同,这里使用的2.x版本。

引入依赖

<!--cache-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

<!--redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

在application.yml文件中配置缓存类型为redis并配置redis的地址、端口、密码等。

spring:
  cache:
    type: REDIS
  redis:
    host: localhost
    port: 6379
    password: 123456
    database: 0

在启动类上增加@EnableCaching注解,没有增加这个注解的话,缓存将不会生效。

至此你已经可以在你的项目中进行redis缓存相关的操作了,但是因为springboot默认使用JdkSerializationRedisSerializer作为redis缓存中value的序列化类,所以你再使用第三方工具去redis中查看value值的时候你看到的将会是一堆乱码,不利于调试。所以我们可以增加一个RedisConfig类来对redis进行自定义的配置

@Configuration
public class RedisConfig {

    /**
     * 默认超时时间
     */
    private static final long DEFAULT_TTL = 999999L;

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        //初始化一个RedisCacheWriter
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
        //自定义key前缀
        CacheKeyPrefix cacheKeyPrefix = new CacheKeyPrefix() {
            @Override
            public String compute(String cacheName) {
                return cacheName+":";
            }
        };
        //设置CacheManager的值序列化方式为json序列化
        RedisSerializer<Object> jsonSerializer = new GenericJackson2JsonRedisSerializer();
        RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair
                .fromSerializer(jsonSerializer);
        //生成RedisCacheConfiguration配置
        RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
                .computePrefixWith(cacheKeyPrefix)
                .serializeValuesWith(pair);
        //设置默认超过期时间是30秒
        defaultCacheConfig.entryTtl(Duration.ofSeconds(DEFAULT_TTL));
        //初始化RedisCacheManager
        return new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
    }

}

新建一个RedisConfig类。类的内容如上,这里我配置了默认过期时间为999999秒,设置redis的key为“cacheName:xxxx”形式,更改value值的序列化为json格式。

现在我们可以愉快的在项目中使用redis了。springboot帮我们针对缓存的操作做了封装。我们可以直接使用注解来方便的使用。

常用的有如下3个注解

  • @Cacheable  使用缓存
  • @CachePut   更新缓存
  • @CacheEvict 清理缓存

他们的参数基本都是一样的,只是功能不同,这里不多展开,只拿@Cacheable进行举例讲解。他的参数及功能解释如下表:

value或cacheNames

缓存名,用于区分不同的业务模块。

在redis的区别就是key前缀会增加“缓存名:”

例如:
@Cacheable(value="mycache")
key

缓存的key,可以为空

指定key需要使用 SpEL 表达式编写

不指定则默认按照方法的所有参数进行组合

@Cacheable(value="testcache",key="#userName")

@Cacheable(value="testcache",key="#root.methodName")

condition

缓存的条件,可以为空

使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存

@Cacheable(value="testcache",condition="#userName.length()>2")

这里为了方便使用。在key中的SpEL表达式中提供了一个root对象,用来做上下文的获取。表达式及解释见下表:

#root.methodName当前被调用的方法名
#root.method当前被调用的方法
#root.target当前被调用的目标对象
#root.targetClass

当前被调用的目标对象类

虽然springboot提供了非常方便的注解供我们使用,但是请注意,因为注解的切入性(这里我理解springboot是使用切面实现的),在同一个类中自己的方法A调用带缓存注解的方法B,此时注解是不会生效的,也就是缓存不会生效。有时候我们实际业务确实有这种需求怎么办?我们可以直接在类中注入springboot提供的模板类来对redis进行操作。

@Autowired
private RedisTemplate redisTemplate;

具体的操作非常简单易懂,网上资料也很多。这里就不过多赘述。

本文相关的一些代码参考:https://gitee.com/floow/blog-demo demo8 测试方法见DemoApplicationTests