官方文档
https://docs.spring.io/spring-framework/docs/5.3.25/reference/html/integration.html#cache
一个应用里要使用缓存,一般要配置一个或几个CacheManager
一、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
二、配置文件配置使用redis作为缓存
spring.cache.type: redis
#还可以设置过期时间,单位毫秒
spring.cache.redis.time-to-live: 360000
三、测试使用缓存
根据官方文档,使用如下5个注释
For caching declaration, Spring’s caching abstraction provides a set of Java annotations:
@Cacheable: Triggers cache population.
(触发将数据保存到缓存的操作)
@CacheEvict: Triggers cache eviction.
(触发将数据从缓存删除的操作,支持失效模式)
如下举例,在更新分类的方法上加上该注释,参数为写入缓存时的value与key值,要与其一样。
当更新数据库时,就会删除该缓存。
@CacheEvict(value = "category",key = "'getLevel1Categorys'")
//若想清楚这一个区(value)的缓存的话,就可按如下下
@CacheEvict(value = "category",allEntries = true)
@CachePut: Updates the cache without interfering with the method execution.
(不影响方法执行更新缓存,支持双写模式)
@Caching: Regroups multiple cache operations to be applied on a method.
(组合以上多个操作)
@Caching(evict = {
@CacheEvict(value = "category",key = "'getLevel1Categorys'"),
@CacheEvict(value = "category",key = "'getCatalogJson'")
})
@CacheConfig: Shares some common cache-related settings at class-level.
(在类级别共享缓存的相同配置)
1、开启缓存功能
在启动类上加上@EnableCaching注释
2、只需要使用注解就能完成缓存操作
如下举例
//查询所有1级分类
//每一个需要缓存的数据我们都来指定要放到那个名字的缓存。【也就是缓存的分区(可按业务类型分)】
//代表当前方法的返回需要缓存,如果缓存中有,方法不用调用。如没有,则调用方法,最后将结果放入缓存
@Cacheable({"category"})
@Override
public List<CategoryEntity> getLevel1Categorys() {
System.out.println("调用了方法....");
long l = System.currentTimeMillis();
QueryWrapper<CategoryEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("parent_cid", 0);
List<CategoryEntity> categoryEntities = baseMapper.selectList(queryWrapper);
System.out.println("消耗时间:" + (System.currentTimeMillis() - l));
return categoryEntities;
}
结果运行来两次后,当第一次访问时,会调用方法。第二次访问时,则不会。
其中它会有如下默认行为:
a)、在redis中会自动生成key,其组成为:缓存的名字::自主生成的key(category::SimpleKey[])
b)、value的值,默认使用jdk序列化机制,将序列化后的数据存到redis
我们可以自定义一些操作:
a)、指定生成的缓存使用的key
使用key属性指定,接受一个SpEL格式语句,若有直接写String格式,则在“”里面加‘’。
@Cacheable(value = {"category"},key = "'level1Categorys'")
结果如下:category::level1Categorys
若想使用方法名作为key,则可更改成如下
@Cacheable(value = {"category"},key = "#root.method.name")
结果如下:category::getLevel1Categorys
由于SprinCache默认是没有加锁的,所以按如下加上sync=true,即可加上本地锁,但只有读模式有,写模式没有
@Cacheable(value = {"category"},key = "#root.method.name",sync = true)
更多SpEL表达式参考官方文档:
b)、指定缓存的数据的存活时间
在配置文件中修改
#设置存活时间,单位毫秒
spring.cache.redis.time-to-live=3600000
c)、将数据保存为json格式
写一个配置类
@Configuration
@EnableCaching
public class MyCacheConfig {
@Bean
RedisCacheConfiguration redisCacheConfiguration(){
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
//设置key的格式为String
config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
//设置value的格式为json
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
return config;
}
}
但只这样配置,会导致在redis中的过期时间变成恒定的-1,没有读取到配置文件中的360000毫秒,所以需要再加上如下配置,即可读取到配置文件中的参数了:
@EnableConfigurationProperties(CacheProperties.class)
@Configuration
@EnableCaching
public class MyCacheConfig {
/*
* 配置文件中的东西没用上
* 1、原来和配置文件绑定的配置类是这样的
* @ConfigurationProperties(prefix="spring.cache")
* public class CacheProperties
*
* 2、要让他生效
* @EnableConfigurationProperties(CacheProperties.class)
*/
@Bean
RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties){
RedisCacheConfiguration config = RedisCacheConfiguration
.defaultCacheConfig();
//设置key的格式为String
config = config.serializeKeysWith(RedisSerializationContext
.SerializationPair
.fromSerializer(new StringRedisSerializer()));
//设置value的格式为json
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.prefixCacheNameWith(redisProperties.getKeyPrefix());
}
if (!redisProperties.isCacheNullValues()) {
config = config.disableCachingNullValues();
}
if (!redisProperties.isUseKeyPrefix()) {
config = config.disableKeyPrefix();
}
return config;
}
}
总结
常规数据(读多写少,即时性,一致性要求不高的数据),完全可以使用spring-cache(只要缓存的数据有过期时间就足够了)
本文介绍了如何使用SpringCache与Redis整合实现缓存功能。通过添加依赖、配置Redis为缓存管理器,利用注解@Cacheable、@CacheEvict、@CachePut等进行缓存操作。在启动类上启用缓存,并通过SpEL定制缓存key和存活时间,以优化数据的读写和一致性。对于需要强一致性的场景,可以设置sync参数以添加本地锁。

164

被折叠的 条评论
为什么被折叠?



