添加以下配置信息;

/**
* 基于注解添加缓存
*/
@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport { private final RedisConnectionFactory redisConnectionFactory; CacheConfig(RedisConnectionFactory redisConnectionFactory) {
this.redisConnectionFactory = redisConnectionFactory;
} @Bean
@Override
public KeyGenerator keyGenerator() {
return (o, method, objects) -> {
StringBuilder sb = new StringBuilder(32);
sb.append(o.getClass().getSimpleName());
sb.append(".");
sb.append(method.getName());
if (objects.length > 0) {
sb.append("#");
}
String sp = "";
for (Object object : objects) {
sb.append(sp);
if (object == null) {
sb.append("NULL");
} else {
sb.append(object.toString());
}
sp = ".";
}
return sb.toString();
};
} /**
* 配置 RedisCacheManager,使用 cache 注解管理 redis 缓存
*/
@Bean
@Override
public CacheManager cacheManager() {
// 初始化一个RedisCacheWriter
RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory); // 设置默认过期时间:30 分钟
RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(30))
// .disableCachingNullValues()
// 使用注解时的序列化、反序列化
.serializeKeysWith(MyRedisCacheManager.STRING_PAIR)
.serializeValuesWith(MyRedisCacheManager.FASTJSON_PAIR); return new MyRedisCacheManager(cacheWriter, defaultCacheConfig);
}
}

redis配置信息:

@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({LettuceConnectionConfiguration.class})
public class RedisConfig { @Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
// set key serializer
StringRedisSerializer serializer = MyRedisCacheManager.STRING_SERIALIZER;
// 设置key序列化类,否则key前面会多了一些乱码
template.setKeySerializer(serializer);
template.setHashKeySerializer(serializer); // fastjson serializer
GenericFastJsonRedisSerializer fastSerializer = MyRedisCacheManager.FASTJSON_SERIALIZER;
template.setValueSerializer(fastSerializer);
template.setHashValueSerializer(fastSerializer);
// 如果 KeySerializer 或者 ValueSerializer 没有配置,则对应的 KeySerializer、ValueSerializer 才使用这个 Serializer
template.setDefaultSerializer(fastSerializer); // factory
template.setConnectionFactory(redisConnectionFactory);
template.afterPropertiesSet();
return template;
} @Bean
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
} }

重写RedisCacheManager

public class MyRedisCacheManager extends RedisCacheManager implements ApplicationContextAware, InitializingBean {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyRedisCacheManager.class);

    private ApplicationContext applicationContext;

    private Map<String, RedisCacheConfiguration> initialCacheConfiguration = new LinkedHashMap<>();

    /**
* key serializer
*/
public static final StringRedisSerializer STRING_SERIALIZER = new StringRedisSerializer(); /**
* value serializer
* <pre>
* 使用 FastJsonRedisSerializer 会报错:java.lang.ClassCastException
* FastJsonRedisSerializer<Object> fastSerializer = new FastJsonRedisSerializer<>(Object.class);
* </pre>
*/ public static final GenericFastJsonRedisSerializer FASTJSON_SERIALIZER = new GenericFastJsonRedisSerializer(); /**
* key serializer pair
*/
public static final RedisSerializationContext.SerializationPair<String> STRING_PAIR = RedisSerializationContext
.SerializationPair.fromSerializer(STRING_SERIALIZER);
/**
* value serializer pair
*/
public static final RedisSerializationContext.SerializationPair<Object> FASTJSON_PAIR = RedisSerializationContext
.SerializationPair.fromSerializer(FASTJSON_SERIALIZER); public MyRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
super(cacheWriter, defaultCacheConfiguration);
} @Override
public Cache getCache(String name) {
Cache cache = super.getCache(name);
return new RedisCacheWrapper(cache);
} @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
} @Override
public void afterPropertiesSet() {
String[] beanNames = applicationContext.getBeanNamesForType(Object.class);
for (String beanName : beanNames) {
final Class clazz = applicationContext.getType(beanName);
add(clazz);
}
super.afterPropertiesSet();
} @Override
protected Collection<RedisCache> loadCaches() {
List<RedisCache> caches = new LinkedList<>();
for (Map.Entry<String, RedisCacheConfiguration> entry : initialCacheConfiguration.entrySet()) {
caches.add(super.createRedisCache(entry.getKey(), entry.getValue()));
}
return caches;
} private void add(final Class clazz) {
ReflectionUtils.doWithMethods(clazz, method -> {
ReflectionUtils.makeAccessible(method);
CacheExpire cacheExpire = AnnotationUtils.findAnnotation(method, CacheExpire.class);
if (cacheExpire == null) {
return;
}
Cacheable cacheable = AnnotationUtils.findAnnotation(method, Cacheable.class);
if (cacheable != null) {
add(cacheable.cacheNames(), cacheExpire);
return;
}
Caching caching = AnnotationUtils.findAnnotation(method, Caching.class);
if (caching != null) {
Cacheable[] cs = caching.cacheable();
if (cs.length > 0) {
for (Cacheable c : cs) {
if (cacheExpire != null && c != null) {
add(c.cacheNames(), cacheExpire);
}
}
}
} else {
CacheConfig cacheConfig = AnnotationUtils.findAnnotation(clazz, CacheConfig.class);
if (cacheConfig != null) {
add(cacheConfig.cacheNames(), cacheExpire);
}
}
}, method -> null != AnnotationUtils.findAnnotation(method, CacheExpire.class));
} private void add(String[] cacheNames, CacheExpire cacheExpire) {
for (String cacheName : cacheNames) {
if (cacheName == null || "".equals(cacheName.trim())) {
continue;
}
long expire = cacheExpire.expire();
LOGGER.info("cacheName: {}, expire: {}", cacheName, expire);
if (expire >= 0) {
// 缓存配置
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(expire))
.disableCachingNullValues()
// .prefixKeysWith(cacheName)
.serializeKeysWith(STRING_PAIR)
.serializeValuesWith(FASTJSON_PAIR);
initialCacheConfiguration.put(cacheName, config);
} else {
LOGGER.warn("{} use default expiration.", cacheName);
}
}
} protected static class RedisCacheWrapper implements Cache {
private final Cache cache; RedisCacheWrapper(Cache cache) {
this.cache = cache;
} @Override
public String getName() {
// LOGGER.info("name: {}", cache.getName());
try {
return cache.getName();
} catch (Exception e) {
LOGGER.error("getName ---> errmsg: {}", e.getMessage(), e);
return null;
}
} @Override
public Object getNativeCache() {
// LOGGER.info("nativeCache: {}", cache.getNativeCache());
try {
return cache.getNativeCache();
} catch (Exception e) {
LOGGER.error("getNativeCache ---> errmsg: {}", e.getMessage(), e);
return null;
}
} @Override
public ValueWrapper get(Object o) {
// LOGGER.info("get ---> o: {}", o);
try {
return cache.get(o);
} catch (Exception e) {
LOGGER.error("get ---> o: {}, errmsg: {}", o, e.getMessage(), e);
return null;
}
} @Override
public <T> T get(Object o, Class<T> aClass) {
// LOGGER.info("get ---> o: {}, clazz: {}", o, aClass);
try {
return cache.get(o, aClass);
} catch (Exception e) {
LOGGER.error("get ---> o: {}, clazz: {}, errmsg: {}", o, aClass, e.getMessage(), e);
return null;
}
} @Override
public <T> T get(Object o, Callable<T> callable) {
// LOGGER.info("get ---> o: {}", o);
try {
return cache.get(o, callable);
} catch (Exception e) {
LOGGER.error("get ---> o: {}, errmsg: {}", o, e.getMessage(), e);
return null;
}
} @Override
public void put(Object o, Object o1) {
// LOGGER.info("put ---> o: {}, o1: {}", o, o1);
try {
cache.put(o, o1);
} catch (Exception e) {
LOGGER.error("put ---> o: {}, o1: {}, errmsg: {}", o, o1, e.getMessage(), e);
}
} @Override
public ValueWrapper putIfAbsent(Object o, Object o1) {
// LOGGER.info("putIfAbsent ---> o: {}, o1: {}", o, o1);
try {
return cache.putIfAbsent(o, o1);
} catch (Exception e) {
LOGGER.error("putIfAbsent ---> o: {}, o1: {}, errmsg: {}", o, o1, e.getMessage(), e);
return null;
}
} @Override
public void evict(Object o) {
// LOGGER.info("evict ---> o: {}", o);
try {
cache.evict(o);
} catch (Exception e) {
LOGGER.error("evict ---> o: {}, errmsg: {}", o, e.getMessage(), e);
}
} @Override
public void clear() {
// LOGGER.info("clear");
try {
cache.clear();
} catch (Exception e) {
LOGGER.error("clear ---> errmsg: {}", e.getMessage(), e);
}
}
}
}

应用:

@GetMapping("/getShopByShopNO/{shopNo}")
public Mono<ShopDO> getShopByShopNO(@PathVariable("shopNo") final String shopNo){
final ShopDO shopByShopNO = shopDAO.getShopByShopNO(shopNo);
return Mono.just(shopByShopNO);
} /**
* 查询店铺详情
* @param shopNo
* @return
*/
@Cacheable(value = "shop",key = "'shop_'.concat(#root.args[0])",sync = true)
@CacheExpire(30)
ShopDO getShopByShopNO(String shopNo);

参考:https://www.cnblogs.com/wjwen/p/9301119.html

基于springboot2.x集成缓存注解及设置过期时间的更多相关文章

  1. redis 一二事 - 设置过期时间,以文件夹形式展示key显示缓存数据

    在使用redis时,有时回存在大量数据的时候,而且分类相同,ID相同 可以使用hset来设置,这样有一个大类和一个小分类和一个value组成 但是hset不能设置过期时间 过期时间只能在set上设置 ...

  2. 可以设置过期时间的Java缓存Map

    前言 最近项目需求需要一个类似于redis可以设置过期时间的K,V存储方式.项目前期暂时不引进redis,暂时用java内存代替. 解决方案 1. ExpiringMap 功能简介 : 1.可设置Ma ...

  3. java操作Redis缓存设置过期时间

    关于Redis的概念和应用本文就不再详解了,说一下怎么在java应用中设置过期时间. 在应用中我们会需要使用redis设置过期时间,比如单点登录中我们需要随机生成一个token作为key,将用户的信息 ...

  4. 29.Jwt集成(3):token设置过期时间、异常判断

    token设置过期时间 package main import ( "fmt" "github.com/dgrijalva/jwt-go" "io/i ...

  5. redis批量设置过期时间

    Redis 中有删除单个 Key 的指令 DEL,但好像没有批量删除 Key 的指令,不过我们可以借助 Linux 的 xargs 指令来完成这个动作.代码如下: redis-cli keys &qu ...

  6. Redis原子性写入HASH结构数据并设置过期时间

    Redis中提供了原子性命令SETEX或SET来写入STRING类型数据并设置Key的过期时间: > SET key value EX NX ok > SETEX key value ok ...

  7. redis中的key设置过期时间

    EXPIRE key seconds 为给定  key  设置生存时间,当  key  过期时(生存时间为  0  ),它会被自动删除. 在 Redis 中,带有生存时间的  key  被称为『易失的 ...

  8. redis文档翻译_key设置过期时间

    Available since 1.0.0.    使用開始版本号1.01 Time complexity: O(1)  时间复杂度O(1) 出处:http://blog.csdn.net/colum ...

  9. 针对永久不过期的key 批量设置过期时间

    问题需求: redis内存暴增,后来发现有很多设置永久不过期. 解决:查找出来之后针对前缀批量设置过期时间 (过期时间与开发沟通 保证服务不受影响) 来源于网上杨一的代码 正好解决了我遇到的问题 在这 ...

随机推荐

  1. 深入玩转K8S之利用Label控制Pod位置

    首先介绍下什么是Label? Label是Kubernetes系列中一个核心概念.是一组绑定到K8s资源对象上的key/value对.同一个对象的labels属性的key必须唯一.label可以附加到 ...

  2. python + selenium + unittest实现简单的UI自动化

    使用的版本是python 3,其中HTMLTestRunner是修改版本,参考以下博客并下载 https://blog.csdn.net/zhanin123/article/details/78950 ...

  3. Eclipse项目上传和下载到码云上

    本文将介绍如何将本地的项目提交到开源中国的码云(版本控制器)上.改教程讲解过程比较详细,跟着做实现起来很简单.由于自己本身也是一个新手,所以不做过多的解释,只是单纯的描述了该如何去做,大家一起学习共同 ...

  4. SQL Server 索引的最佳实践

    索引设计是数据库设计中比较重要的一个环节,对数据库的性能其中至关重要的作用,但是索引的设计却又不是那么容易的事情,性能也不是那么轻易就获取到的,很多的技术人员因为不恰当的创建索引,最后使得其效果适得其 ...

  5. [转帖]SSD和内存数据库技术

    SSD和内存数据库技术 自己的理解还是不是很对 SSD 提升的是 随机读 并没有对顺序写有多大的提升, 因为数据库采用的是redo的模式. 理论上写入 时是顺序写 所以 写并发的提升不会很大 但是会很 ...

  6. Python使用队列实现Josephus问题

    Josephus问题,在这个古老的问题中,N个深陷绝境的人一致同意通过以下方式减少生存的人数.他们围坐一圈(位置记为0~N-1)并从第一个人报数,报到M的人会被杀死, 知道最后一个人留下来.传说中Jo ...

  7. 深度学习-深度强化学习(DRL)-Policy Gradient与PPO笔记

    Policy Gradient 初始学习李宏毅讲的强化学习,听台湾的口音真是费了九牛二虎之力,后来看到有热心博客整理的很细致,于是转载来看,当作笔记留待复习用,原文链接在文末.看完笔记再去听一听李宏毅 ...

  8. nginx静态文件不设置缓存

    找到nginx安装目录下的nginx.conf文件,再nginx里面添加如下的内容 location / { add_header Cache-Control no-cache; add_header ...

  9. HBase 系列(三)—— HBase 基本环境搭建

    一.安装前置条件说明 1.1 JDK版本说明 HBase 需要依赖 JDK 环境,同时 HBase 2.0+ 以上版本不再支持 JDK 1.7 ,需要安装 JDK 1.8+ .JDK 安装方式见本仓库 ...

  10. copy file

    import io,,,,,,, from https://pub.dev/packages/large_file_copy Directory directory = await getApplic ...