SpringBoot使用@Cacheable时设置部分缓存的过期时间方式

网友投稿 2367 2022-09-07


SpringBoot使用@Cacheable时设置部分缓存的过期时间方式

目录使用@Cacheable时设置部分缓存的过期时间业务场景rUaCygEeB添加Redis配置类RedisConfig.java@Cacheable自定义缓存过期时间pomymlRedisConfigCustomRedisCacheManager使用

使用@Cacheable时设置部分缓存的过期时间

业务场景

Spring Boot项目中有一些查询数据需要缓存到Redis中,其中有一些缓存是固定数据不会改变,那么就没必要设置过期时间。还有一些缓存需要每隔几分钟就更新一次,这时就需要设置过期时间。

Service层部分代码如下:

@Override

@Cacheable(cacheNames = {"distributor"}, key = "#root.methodName")

public List findCities() {

return distributorMapper.selectCities();

}

@Override

@Cacheable(cacheNames = {"distributor"}, key = "#root.methodName.concat('#cityId').concat(#cityId)")

public List findDistributorsByCityId(String cityId) {

return distributorMapper.selectByCityId(cityId);

}

@Override

@Cacheable(cacheNames = {"car"}, key = "#root.methodName.concat('#cityId').concat(#cityId)")

public String carList(String cityId) {

RequestData data = new RequestData();

data.setCityId(cityId);

CarListParam param = new CarListParam();

param.setRequestData(data);

String jsonParam = JSON.toJSONString(param);

return HttpClientUtil.sendPostWithJson(ApiUrlConst.MULE_APP, jsonParam);

}

在使用@Cacheable注解对查询数据进行缓存时,使用cacheNames属性指定了缓存名称。下面我们就针对不同的cacheNames来设置失效时间。

添加Redis配置类RedisConfig.java

代码如下:

@Slf4j

@Configuration

@EnableCaching //启用缓存

public class RedisConfig {

/**

* 自定义缓存管理器

*/

@Bean

public RedisCacheManager cacheManager(RedisConnectionFactory factory) {

RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();

Set cacheNames = new HashSet<>();

cacheNames.add("car");

cacheNames.add("distributor");

ConcurrentHashMap configMap = new ConcurrentHashMap<>();

configMap.put("car", config.entryTtl(Duration.ofMinutes(6L)));

configMap.put("distributor", config);

//需要先初始化缓存名称,再初始化其它的配置。

RedisCacheManager cacheManager = RedisCacheManager.builder(factory).initialCacheNames(cacheNames).withInitialCacheConfigurations(configMap).build();

return cacheManager;

}

}

上面代码,在configMap中指定了cacheNames为car的缓存过期时间为6分钟。

@Cacheable自定义缓存过期时间

pom

org.springframework.boot

spring-boot-starter-data-redis

org.apache.commons

commons-pool2

yml

# redis配置

spring:

redis:

database: 0

host: 127.0.0.1

pashttp://sword: 123456

port: 6379

timeout: 5000

lettuce:

pool:

max-active: 300

max-wait: -1

max-idle: 20

min-idle: 10

RedisConfig

RedisCacheManager:缓存默认不过期,所以这里返回自定RedisCacheManager

//return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);

return new CustomRedisCacheManager(redisCacheWriter, redisCacheConfiguration);

@Configuration

public class RedisConfig {

/*

* @description redis序列化方式

* @author xianping

* @date 2020/9/25

* @param redisConnectionFactory

* @return RedisTemplate

**/

@Bean

public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {

RedisTemplate redisTemplate = new RedisTemplate();

redisTemplate.setConnectionFactory(redisConnectionFactory);

Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

ObjectMapper objectMapper = new ObjectMapper();

objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

redisTemplate.setKeySerializer(new StringRedisSerializer());

redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);

redisTemplate.setHashKeySerializer(new StringRedisSerializer());

redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);

redisTemplate.afterPropertiesSet();

return redisTemplate;

}

/*

* @description Redis缓存的序列化方式使用redisTemplate.getValueSerializer(),不在使用JDK默认的序列化方式

* @author xianping

* @date 2020/9/25

* @param redisTemplate

* @return RedisCacheManager

**/

@Bean

public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {

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

RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()

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

//return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);

return new CustomRedisCacheManager(redisCacheWriter, redisCacheConfiguration);

}

}

CustomRedisCacheManager

自定义RedisCacheManager:若@Cacheable value中包含'#‘号,则'#'后为缓存生存时间,不存在则表示缓存不进行生存时间设置

//cacheConfig.entryTtl 设置缓存过期时间

public RedisCacheConfiguration entryTtl(Duration ttl) {

Assert.notNull(ttl, "TTL duration must not be null!");

return new RedisCacheConfiguration(ttl, this.cacheNullValues, this.usePrefix, this.keyPrefix, this.keySerializationPair, this.valueSerializationPair, this.conversionService);

}

//Duration.ofMinutes 持续时间

//这里默认是以分钟为单位,所以调用ofMinutes静态方法进行转换

public static Duration ofMinutes(long minutes) {

return create(Math.multiplyExact(minutes, SECONDS_PER_MINUTE), 0);

}

public class CustomRedisCacheManager extends RedisCacheManager {

/*

* @description 提供默认构造器

* @author xianping

* @date 2020/9/28 9:22

* @param

* @param cacheWriter

* @param defaultCacheConfiguration

* @return

**/

public CustomRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {

super(cacheWriter, defaultCacheConfiguration);

}

/*

* @description 重写父类createRedisCache方法

* @author xianping

* @date 2020/9/28 9:22

* @param

* @param name @Cacheable中的value

* @param cacheConfig

* @return org.springframework.data.redis.cache.RedisCache

**/

@Override

protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {

//名称中存在#标记进行到期时间配置

if (!name.isEmpty() && name.contains("#")) {

String[] SPEL = name.split("#");

if (StringUtils.isNumeric(SPEL[1])) {

//配置缓存到期时间

int cycle = Integer.parseInt(SPEL[1]);

return super.createRedisCache(SPEL[0], cacheConfig.entryTtl(Duration.ofMinutes(cycle * 24 * 60)));

}

}

return super.createRedisCache(name, cacheConfig);

}

}

使用

生存时间1天

@Cacheable(value = "cacheTest#1")

public String cacheTest() {

return "cacheTest";

}

缓存持久,无过期时间

@Cacheable(value = "cacheTest")

public String cacheTest() {

return "cacheTest";

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Python编程高级技巧| 选择好的名称(python基础教程用编程狮)
下一篇:Python数据结构之合集(python最基本的数据结构)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~