基于 Spring Boot 的配置,为例来让 Spring Cache 和 Spring Data Redis 结合使用。不同的 Spring Boot 版本,可能源码或者细节有点区别,但是基本思路和思想是不变的。
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.timeout=6000
spring.redis.pool.max-active=8
spring.redis.pool.max-idle=8
spring.redis.pool.max-wait=-1
spring.redis.pool.min-idle=0
通过第三节,可以知道,我们这里默认用 Redis 的 pool 的配置方式。
如:我们在 Controller 里面调用 JPA 的方法上添加 @Cacheable 即可使用。
- curl http://127.0.0.1:8080/hello/users 就会发现,第一次会进入到 Controller 的 method 里面,第二次就不进去了。
- 我们打开 redis-client 可以看到,Reids 的 Server 端已经有我们的缓存了。
- Spring Cache 和 Spring Data Redis 两个 jar 的引入。
- 在 application.properties 配置我们第02课介绍 Spring Data Redis 的正确配置方法即可。
- 在用到的地方直接用我们第03课讲到的 Cacheable 相关的配置即可。
- 也可以在 application.properties 指定 spring.cache.type=redis。改变 Cache 的默认行为,让其用 Redis 来实现。
- 最后,会发现代码变的优雅很多比起原始的配置。
- 当我们引入 spring-boot-starter-data-redis 的时候我们第02课讲过,会自动把 Spring Data Redis 的 jar 也加入进来,同时会激活 RedisCacheConfiguration,把 RedisCacheManager 给默认加载进来。
- 当我们引入 spring-boot-starter-cache 的时候我们第03课讲过,会自动加载 CacheAutoConfiguration,并且里面 CacheType 有顺序,这时候会把 RedisCacheManager 给激活。
当我们打断点在这个类上的时候,会发现 cacheManager 这时候会变成 RedisCacheManager,而不是默认的 Cache Manager。
给大家留个问题,怎么用 Redis 经典 sentinel 和 cluster 模式与 Cache 结合。
而实际生产环境可能不像 Demo 这么随意,接下来说一下都有哪些自定义场景,如何自定义。
- 通过课04,我们知道关键类 CacheConfigurationImportSelector,找到 CacheConfigurations 关键代码如下:
- 通过这个我们发现了 Redis 的 Type 类型的 Cache 调用的是 RedisCacheConfiguration。
通过 RedisCacheConfiguration 其实可以发现很多:如可以自定义 Redis 的 Configuration 和自定义 Redis 的 CacheManager。
- 通过04课,也提到了 CachingConfigurer,是 Spring 为我们预留的自定义接口,打开它的默认实现类 CachingConfigurerSupport。
通过继承此类就可以实现自定义 cacheManager 和 KeyGenerator、CacheResolver、CacheErrorHandler。
(1)新建 RedisConfiguration,并且配置两个 CacheManager。
我们都知道 RedisTemplae 和 StringRedisTemplate 的默认的:
setKeySerializer(stringSerializer);
setValueSerializer(stringSerializer);
setHashKeySerializer(stringSerializer);
setHashValueSerializer(stringSerializer);
都是不一样的,所以我们分别配置了两个 CacheManager。以至于我们在配置 @Cacheable(value = "user",cacheManager = "redisCacheManagerString") 可以选择用哪个 cacheManager。这里只是举例了工作频率最高的自定义配置,通过之定义 CacheManager 实现了三件事不一样如下:
- defaultExpiration:默认过期时间是不一样的。
- 不同的 Cache 的 Name 我们也可以定制化,不一样的过期时间。
- 不同的 Cache 我们可以选择不同的 RedisTemplate。
(2)自定义 KeyGenerator 覆盖默认的 Cache key 生成规则,只需要在 RedisConfiguration 中增加如下配置即可。
(3)修改 RedisTemplate 和 StringRedisTemplate 的 KeySerializer 和 ValueSerializer 默认规则。
(4)使用的地方 controller 配置如下:
(5)我们调用 http://127.0.0.1:8080/hello/users 得到的结果如下:
到此完美的自定义过程。
当使用 @Cacheable 的注解的时候一定要加 condition 和 unless,对结果和查询条件进行过滤。这样可以避免一些用户体验不好的地方。
自此上面所有的源码在 GitHub 上,详见这里,欢迎大家一起提交和改进。