Spring Cache :
-
官方文档: https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#cache-annotations
-
cache 操作缓存数据
-
依赖
<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>
-
cache 相关缓存注解
// 触发缓存填充。
@Cacheable: Triggers cache population.
// 触发缓存逐出。
@CacheEvict: Triggers cache eviction.
// 在不干扰方法执行的情况下更新缓存。
@CachePut: Updates the cache without interfering with the method execution.
// 重新组合要在一个方法上应用的多个缓存操作。
@Caching: Regroups multiple cache operations to be applied on a method.
// 在类级别共享一些与缓存有关的常见设置。
@CacheConfig: Shares some common cache-related settings at class-level.
// 开启缓存功能
@EnableCaching
@Cacheable:
-
默认行为:
- 使用在方法上该方法的返回结果将存入缓存中, 注解里需标注缓存名
- 该注解会根据备注的缓存名自动生成 key , 返回结果作为value存入缓存
- 默认的过期时间为 -1
-
自定义行为:
-
指定生成的key key属性字段使用 SPEL表达式 (key = " ‘key的名称’ ")
-
指定缓存数据的存活时间 在配置文件中配置存活时间
-
指定缓存数据的格式为JSON 需自定义缓存管理器
自定义RedisCacheConfiguration 配置缓存的序列化方式, 默认的序列化方式为 JDK 序列化方式
-
使用该注解的 sync属性, 可以解决缓存击穿问题, 大量并发查询同一个快过期的缓存
-
-
自动配置原理:
自动配置类:CacheAutoConfiguration -> RedisCacheConfiguration -> 注入RedisCacheManager 初始化所有缓存, 进行缓存配置, 会使用默认的RedisCacheConfiguration进行配置, 当用户自定义了该配置类时, 就使用自定义的的配置
-
自定义配置类:
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.StringRedisSerializer; /** * @ClassName CacheConfig * @author: fangwenjun * @date: Created in 2021/3/23 9:25 * @description: * @version: 1.0 */ // 开启 把配置文件中的 @EnableConfigurationProperties(CacheProperties.class) @EnableCaching @Configuration public class CacheConfig { @Bean RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) { RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); // 每次设置配置时都会创建新的对象返回, 所以要用之前的对象进行覆盖 // 配置缓存的序列化方式, 分别设置 key 和 value 的序列化方式 config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())); config = 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) { // key值 前缀 config = config.prefixKeysWith(redisProperties.getKeyPrefix()); } if (!redisProperties.isCacheNullValues()) { // 缓存空值 防止缓存穿透 config = config.disableCachingNullValues(); } if (!redisProperties.isUseKeyPrefix()) { // 使用 前缀 config = config.disableKeyPrefix(); } return config; } }
@CacheEvict:
-
清楚缓存
-
使用方式:
// 删除指定分区下的指定单个缓存 @CacheEvict(value = "category",key = "'getLevel1Category'") // 删除指定分区下的所有缓存 @CacheEvict(value = "category", allEntries = true) // 组合多组操作, 可以是删除缓存, 更新缓存 @Caching(evict = { @CacheEvict(value = "category",key = "'getLevel1Category'"), @CacheEvict(value = "category",key = "'getCatelogJson'") }) @Override @Transactional(rollbackFor = Exception.class) public void updateDetail(CategoryEntity category) { this.updateById(category); categoryBrandRelationService.updateBrandAndCategpry(category); }