前提
可以通过以下方法统一过期时间,就是不太实用
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
//设置缓存过期时间
RedisCacheConfiguration redisCacheCfg=RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(STRING_SERIALIZER))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(JACKSON__SERIALIZER));
return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
.cacheDefaults(redisCacheCfg)
.build();
}
自定义注解实现
1、实现思路:通过spring相关方法拿到所有 自定义的注解,将过期时间设置到对应key里
新建类RedisTimeCacheManager 继承 RedisCacheManager 重写loadCaches()方法
实现 ApplicationContextAware 用于通过 applicationContext 拿到所有 自定义的注解
实现 InitializingBean 用于执行 afterPropertiesSet方法
2、代码如下
/**
* @author xhji
*/
@Slf4j
public class RedisTimeCacheManager extends RedisCacheManager implements ApplicationContextAware, InitializingBean {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
private Map initialCacheConfiguration = new LinkedHashMap<>();
/**
* key serializer
*/
public static final StringRedisSerializer STRING_SERIALIZER = new StringRedisSerializer();
/**
* value serializer
*
* 使用 FastJsonRedisSerializer 会报错:java.lang.ClassCastException
* FastJsonRedisSerializer
*/
public static final GenericFastJsonRedisSerializer FASTJSON_SERIALIZER = new GenericFastJsonRedisSerializer();
/**
* key serializer pair
*/
public static final RedisSerializationContext.SerializationPair STRING_PAIR = RedisSerializationContext
.SerializationPair.fromSerializer(STRING_SERIALIZER);
/**
* value serializer pair
*/
public static final RedisSerializationContext.SerializationPair
/**
* @author xhji
*/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport{
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
// 初始化一个RedisCacheWriter
RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
//设置默认缓存过期时间
RedisCacheConfiguration defaultCacheConfig=RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1))
.serializeKeysWith(RedisTimeCacheManager.STRING_PAIR)
.serializeValuesWith(RedisTimeCacheManager.FASTJSON_PAIR);
return new RedisTimeCacheManager(cacheWriter, defaultCacheConfig);
}
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate redisTemplate(RedisConnectionFactory factory){
// 配置redisTemplate
RedisTemplate redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
// key序列化
redisTemplate.setKeySerializer(RedisTimeCacheManager.STRING_SERIALIZER);
// value序列化
redisTemplate.setValueSerializer(RedisTimeCacheManager.FASTJSON_SERIALIZER);
// Hash key序列化
redisTemplate.setHashKeySerializer(RedisTimeCacheManager.STRING_SERIALIZER);
// Hash value序列化
redisTemplate.setHashValueSerializer(RedisTimeCacheManager.FASTJSON_SERIALIZER);
// 如果 KeySerializer 或者 ValueSerializer 没有配置,则对应的 KeySerializer、ValueSerializer 才使用这个 Serializer
redisTemplate.setDefaultSerializer(RedisTimeCacheManager.FASTJSON_SERIALIZER);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
/**
* @author xhji
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CacheExpire {
/**
* expire time, default 60s
*/
@AliasFor("expire")
long value() default 60L;
/**
* expire time, default 60s
*/
@AliasFor("value")
long expire() default 60L;
/**
* 时间单位
*
* @return
*/
TimeType type() default SECONDS;
}
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.function.Function;
public enum TimeType {
SECONDS(Duration::ofSeconds),
MINUTES(Duration::ofMinutes),
HOURS(Duration::ofHours),
DAY(Duration::ofDays),
WEEK(week -> {
LocalDateTime now = LocalDateTime.now();
return Duration.between(now, now.plusWeeks(week));
}),
MONTH(month -> {
LocalDateTime now = LocalDateTime.now();
return Duration.between(now, now.plusMonths(month));
}),
YEAR(year -> {
LocalDateTime now = LocalDateTime.now();
return Duration.between(now, now.plusYears(year));
});
TimeType(Function duration) {
this.duration = duration;
}
public Function duration;
}
项目地址:https://gitee.com/xhji/spiderboot