1.简介
之前我们说了关于读模式写模式的一些概念,以及对于缓存一致性的解决方案
这一次说的是spring cache,相当于简化前面的固有操作,可以理解为对缓存的一个抽象,他是spring集成组件的一部分,
有了他的话我们使用缓存就简单多了,之前许多操作往往一个注解就搞定了,官方学习链接如下
https://docs.spring.io/spring-framework/docs/5.2.13.RELEASE/spring-framework-reference/
2.进一步了解
应用要使用springcache,要给应用配一到多个缓存管理器,而一个缓存管理器中又有着不同的缓存组件,真正对缓存进行增删改查是靠这些缓存组件
这些缓存用名字来区分,如下图 比如分为员工缓存,薪水的缓存,菜单缓存,商品缓存,其它缓存等等
其实呢,简单理解起来,CacheManager作为一个管理器,就是用来定义规则的,比如存储是使用ConcurrentMap还是redis还是mysql还是mongodb,
又或者混存整体的过期时间啥的,而缓存组件为啥要用不同名称来划分呢,这个其实是跟你业务相关的,比如你可以定单业务,商品业务各定义一块缓存,
然后新增删除的时候就可以细分到这一块缓存,比如你要刷新定单业务的缓存,总不好全部刷新吧
CacheManager Cache 这俩父接口,可以点开去看看有哪些方法
3.整合SpringCache与初步体验注解的方便
(1)引入依赖
第一个是springcache的依赖,第二个是你要使用什么作为缓存场景就引入啥,我们这里是redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
(2)写配置
先看下引入依赖后帮我们自动配置了啥,才知道缺啥配置我们就可以手动去补
看了CacheAutoConfiguration代码后,发现里面会配对应类型缓存管理器,我们这是redis然后创建缓存空间
(3)开启缓存功能
添加以下第一个注解即可
(4)各注解使用方式
先做一个各个注解的简单介绍
4.1 @Cacheable
把注解加到之前访问首页就会调用的查询一级分类的方法上
我访问并刷新首页,只有第一次打印了输出语句,说明保存到缓存里了,后面的方法的调用其实是直接访问的缓存,
如果缓存内没有实际还是会访问方法的,不信你把缓存删掉试试
打开redis客户端,找到这个缓存,可以看到他的key是默认的,过期时间 -1是永不过期,值是jdk序列化的结果,这些我们后面都可以自己定义的
4.2 修改各种默认配置
前面这一句我们现在来实现下
@Cacheable中的各种属性
下图可以看到Cacheable中的各种属性,我们上面只设置了值,其实还可以设置key或者key的生成器,设置什么条件缓存,什么条件不缓存等等是否同步啥的
4.2.1设置key
如下,记得key是使用SpEL表达式,比如字符串就要记得再加俩单引号
http://SpEL表达式链接 key可以为方法名啥的
4.2.2设置过期时间
这个我们之前说了,自动配置类会加载application.properties配置文件
这里我们过期时间设置为一小时
4.3.3把缓存中的值改为json格式,防止兼容性问题
这里就需要自定义配置类了,过程我不多说,阅读
RedisCacheConfiguration后 得知,我们自定义配置类,并覆盖redisconfig对象,以及添加自己的配置即可
package com.atguigu.gulimall.product.config;
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @author rengang
* @version 1.0
* @date 2021/3/28 15:47
*/
@EnableConfigurationProperties(CacheProperties.class)
@Configuration
@EnableCaching
public class MyCacheConfig {
@Bean
RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties){
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
//键值 缓存类型设置 键采用string 值采用 generic json 也就是支持泛型的json
config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericFastJsonRedisSerializer()));
CacheProperties.Redis redisProperties = cacheProperties.getRedis();
if (redisProperties.getTimeToLive() != null) {
config = config.entryTtl(redisProperties.getTimeToLive());
}
if (redisProperties.getKeyPrefix() != null) {
config = config.prefixKeysWith(redisProperties.getKeyPrefix());
}
if (!redisProperties.isCacheNullValues()) {
config = config.disableCachingNullValues();
}
if (!redisProperties.isUseKeyPrefix()) {
config = config.disableKeyPrefix();
}
return config;
}
}
application.properties
spring.cache.type=redis
spring.cache.cache-names= music,pic
spring.cache.redis.time-to-live= 3600000
spring.cache.redis.key-prefix= Cache-
#缓存空值,默认就是true
spring.cache.redis.cache-null-values= true
再打开redis客户端工具,可以看到上面对缓存的各种配置都生效了