回顾Spring cache使用
1. 引用依赖
<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.配置
在启动类上加上@EnableCaching注解
3.使用
在需要的方法上加@Cacheable注解,需要注意@Cacheable的几个参数:
- value、cacheNames: 两个等同的参数(cacheNames为Spring 4新增,作为value的别名),用于指定缓存存储的集合名。由于Spring 4中新增了@CacheConfig,因此在Spring 3中原本必须有的value属性,也成为非必需项。
- key: 缓存对象存储在Map集合中的key值,非必需,缺省按照函数的所有参数组合作为key值,若自己配置需使用SpEL表达式,比如:@Cacheable(key = “#p0”):使用函数第一个参数作为缓存的key值
解决问题
可以看出@Cacheable并没有设置过期时间的参数。解决办法:
配置CacheManager:
@Getter
public enum CacheEnums {
/**
* 查询用户信息
*/
SELECT_BY_USERNAME("user/select/selectByUsername","查询用户信息",20),
;
/**
* cacheNames
*/
@Getter
final String cacheNames;
/**
* 描述
*/
@Getter
final String desc;
/**
* 有效时间 单位秒
*/
@Getter
final long ttl;
CacheEnums( String cacheNames,String desc,long ttl) {
this.cacheNames = cacheNames;
this.desc = desc;
this.ttl = ttl;
}
public static CacheEnums getByValue(String cacheNames) {
for (CacheEnums e : values()) {
if (e.cacheNames.compareTo(cacheNames) == 0) {
return e;
}
}
return null;
}
}
@Configuration
@EnableCaching
public class RedisCacheConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
/**
* @param template
* @return
*/
@Bean
public CacheManager cacheManager(RedisTemplate<String, Object> template) {
RedisCacheManager.RedisCacheManagerBuilder managerBuilder = RedisCacheManager.RedisCacheManagerBuilder
.fromConnectionFactory(Objects.requireNonNull(template.getConnectionFactory()))
// 缓存配置
.cacheDefaults(getCacheTtlConfiguration(template, 60 * 60));
for (CacheEnums e : CacheEnums.values()) {
managerBuilder.withCacheConfiguration(e.getCacheNames(), getCacheTtlConfiguration(template, e.getTtl()));
}
return managerBuilder
// 配置同步修改或删除 put/evict
.transactionAware()
.build();
}
public RedisCacheConfiguration getCacheTtlConfiguration(RedisTemplate<String, Object> template, long seconds) {
return RedisCacheConfiguration
.defaultCacheConfig()
// 设置key为String
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(template.getStringSerializer()))
// 设置value 为自动转Json的Object
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(template.getValueSerializer()))
// 不缓存null
.disableCachingNullValues()
// 缓存数据保存1小时
.entryTtl(Duration.ofSeconds(seconds));
}
}
- getCacheTtlConfiguration()方法可以配置CacheConfiguration的有效时间。
- 将该CacheConfiguration作为参数放到managerBuilder.withCacheConfiguration()中,就实现了对缓存的有效时间配置。
- 维护了一个CacheEnums的枚举,避免了修改该配置类,直接在枚举中配置。
- 记得在配置类上加上@EnableCaching注解,当然也可以把这个CacheManager的Bean放到启动类下。
- 枚举中的cacheNames就是@Cacheable中参数value、cacheNames的内容,可以将一系列类似的缓存配置一样的有效时间。