为什么使用?
写缓存逻辑太麻烦了,是用SpringCache缓存框架,方便的注解
引入
<!--springCache-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
注解
@Cacheable 当前方法的结果需要缓存,如果缓存中有直接返回,没有则调用方法再放入缓存,需要指定缓存的分区
@Cacheable (value = {"category"})
@CacheEvict ---触发将数据从缓存中删除的方法 失效模式
@CachePut ---不影响方法执行更新缓存 双写模式
@Caching ---组合以上多个操作
@CacheConfig ---在类级别共享缓存的相同配置
1.开启缓存
@EnableCaching
spring.cache.type=redis #properties配置文件中配置
2.可以使用自定义的配置
@EnableConfigurationProperties(CacheProperties.class) //开启属性配置的绑定功能
@Configuration
@EnableCaching //开启缓存
public class myCacheConfig {
@Bean
public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
//修改序列化方式
config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
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;
}
}
yml配置文件
#缓存类型
spring.cache.type=redis
#key的存活时间
spring.cache.redis.time-to-live=3600000
#key默认前缀,默认前缀是分区名
#spring.cache.redis.key-prefix=CACHE_
#是否开始使用key默认前缀
spring.cache.redis.use-key-prefix=true
#是否缓存空值
spring.cache.redis.cache-null-values=true
3.使用注解
//@CacheEvict(value = {"category"}, key = "'getLevelOneCategory'") //失效模式--改完删除缓存,保证数据一致性
//组合多个操作
/*@Caching(evict = {
@CacheEvict(value = {"category"}, key = "'getLevelOneCategory'"),
@CacheEvict(value = {"category"}, key = "'getCatalgJson'")
})*/
//删除某个缓存分区中的所有数据
@CacheEvict(value = "category",allEntries = true)
@Cacheable(value = {"category"}, key = "#root.method.name")
如何加锁解决缓存击穿?
@Cacheable(value = {"category"}, key = "#root.method.name",sync = true)
sync表示加锁(本地),其他注解中没有sync属性
写模式需要自己进行加锁,如读写锁等根据不同情况
总结:对数据即时性,一致性要求不高,读多写少使用springcache没有问题
对于某些特殊数据需求自己进行特殊的缓存和加锁的设计