springboot基础(66):spring缓存@Cacheable设置缓存有效期

springboot基础(66):spring缓存@Cacheable设置缓存有效期

文章目录

前言设置时间传送门

前言

在使用@Cacheable注解时,数据被缓存到redis服务器,但是没有设置失效时间。 查看Cacheable的源码,也没有提供设置缓存时间的属性和办法。如何给缓存设置时间呢?

设置时间

在@Cacheable注解设置时间(cachespace自定义的命名缓存空间,30标识缓存30秒)

@Cacheable(value="cachespace=30",key="#id") //#id表示读取形参里名称为id的值,value表示缓存空间(自定义名称)

public Book queryById(Integer id) {

System.out.println("读取数据库:id="+id);

return bookMapper.selectById(id);

}

需要自定义TtlRedisCacheManager扩展RedisCacheManager

package com.it2.springbootmybatisplus.config;

import org.springframework.data.redis.cache.RedisCache;

import org.springframework.data.redis.cache.RedisCacheConfiguration;

import org.springframework.data.redis.cache.RedisCacheManager;

import org.springframework.data.redis.cache.RedisCacheWriter;

import org.springframework.util.StringUtils;

import java.time.Duration;

public class TtlRedisCacheManager extends RedisCacheManager {

public TtlRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {

super(cacheWriter, defaultCacheConfiguration);

}

@Override

protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {

System.out.println(name);

String[] cells = StringUtils.delimitedListToStringArray(name, "=");

name = cells[0];

if (cells.length > 1) {

long ttl = Long.parseLong(cells[1]);

// 根据传参设置缓存失效时间,默认单位是秒

cacheConfig = cacheConfig.entryTtl(Duration.ofSeconds(ttl));

}

return super.createRedisCache(name, cacheConfig);

}

}

自定义RedisCacheManager,需要加载到容器中

/**

* 自定义RedisCacheManager,用于在使用@Cacheable时设置ttl

*/

@Bean

public RedisCacheManager selfCacheManager(RedisTemplate redisTemplate) {

RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory());

RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()

.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));

return new TtlRedisCacheManager(redisCacheWriter, redisCacheConfiguration);

}

完整代码

package com.it2.springbootmybatisplus.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;

import com.fasterxml.jackson.annotation.PropertyAccessor;

import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.extern.slf4j.Slf4j;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.data.redis.cache.RedisCacheConfiguration;

import org.springframework.data.redis.cache.RedisCacheManager;

import org.springframework.data.redis.cache.RedisCacheWriter;

import org.springframework.data.redis.connection.RedisConnectionFactory;

import org.springframework.data.redis.connection.RedisPassword;

import org.springframework.data.redis.connection.RedisStandaloneConfiguration;

import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;

import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import org.springframework.data.redis.serializer.RedisSerializationContext;

import org.springframework.data.redis.serializer.StringRedisSerializer;

import redis.clients.jedis.JedisPoolConfig;

@Configuration

@Slf4j

public class MyCacheConfig {

/**

* 定义redis连接池参数,详细参数配置请查阅资料

* */

@Bean

public JedisPoolConfig jedisPool() {

JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();

jedisPoolConfig.setMaxIdle(100);

jedisPoolConfig.setMaxWaitMillis(1000);

jedisPoolConfig.setMaxTotal(100);

jedisPoolConfig.setMinIdle(10);

return jedisPoolConfig;

}

/**

* 配置Redis的连接,从系统环境变量中取值

* 使用单机部署配置

* */

@Bean

public RedisStandaloneConfiguration jedisConfig() {

RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();

int port=(null==System.getenv("REDIS_PORT")?6379:new Integer(System.getenv("REDIS_PORT")));

String hostName=(null==System.getenv("REDIS_HOST")?"127.0.0.1":System.getenv("REDIS_HOST"));

String password=(null==System.getenv("REDIS_PSWD")?null:System.getenv("REDIS_PSWD"));

log.info("Init redis connection - port:{},host:{}",port,hostName);

config.setHostName(hostName);

config.setPort(port);

config.setDatabase(0);

config.setPassword(RedisPassword.of(password));

return config;

}

@Bean

public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPool,

RedisStandaloneConfiguration jedisConfig) {

//配置使用连接池,如果用默认的连接池策略直接builder.build()即可

JedisClientConfiguration jedisClientConfiguration =

JedisClientConfiguration.builder().usePooling().poolConfig(jedisPool).build();

return new JedisConnectionFactory(jedisConfig, jedisClientConfiguration);

}

@Bean

public RedisTemplate redisTemplate(RedisConnectionFactory factory) {

RedisTemplate template = new RedisTemplate<>();

template.setConnectionFactory(factory);

// 使用Jackson2JsonRedisSerialize 替换默认的jdkSerializeable序列化

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;

}

/**

* 自定义RedisCacheManager,用于在使用@Cacheable时设置ttl

*/

@Bean

public RedisCacheManager selfCacheManager(RedisTemplate redisTemplate) {

RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory());

RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()

.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));

return new TtlRedisCacheManager(redisCacheWriter, redisCacheConfiguration);

}

}

主类上开启@EnableCaching //开启缓存 启动服务器测试,发起请求,可以看到缓存的TTL不是-1(剩余秒数)

传送门

如果不清楚如何使用@Cacheable,请见 springboot基础(37):spring缓存@Cacheable和@CacheEvict

猜你喜欢

为什么屁股总是凉凉的?3个生理知识,男女都该看看
约彩365彩票app下载安装

为什么屁股总是凉凉的?3个生理知识,男女都该看看

📅 07-27 ❤️ 270
玩家攻略:110级翅膀打造攻略
365APP

玩家攻略:110级翅膀打造攻略

📅 07-24 ❤️ 582
今年国产软件板块牛股成群,哪些基金受益? 当地时间7月18日, 微软 在 Microsoft Inspire大会上宣布,其与Office软件配套使用的新企业人工智...
DB2锁表和解锁
365APP

DB2锁表和解锁

📅 07-07 ❤️ 532
作业帮如何退出登录账号
约彩365彩票app下载安装

作业帮如何退出登录账号

📅 07-01 ❤️ 706
开发一款棋牌游戏需要多长时间?需要做哪些准备?
det365娱乐场所官方网

开发一款棋牌游戏需要多长时间?需要做哪些准备?

📅 07-05 ❤️ 574
【新人向——编织加蛋,无限套娃刷装】
约彩365彩票app下载安装

【新人向——编织加蛋,无限套娃刷装】

📅 06-28 ❤️ 863
不忘初心,怀念八冠王!金英权再登世俱杯,致敬广州队辉煌岁月
18款电子名片工具:提高90%办公效率的电子名片工具和编辑平台