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

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

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

业务场景

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

Service层部分代码如下:

@Override@Cacheable(cacheNames = {"distributor"}, key = "#root.methodName")public List<CityVO> findCities() { return distributorMapper.selectCities();}@Override@Cacheable(cacheNames = {"distributor"}, key = "#root.methodName.concat('#cityId').concat(#cityId)")public List<DistributorVO> 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<String> cacheNames = new HashSet<>();  cacheNames.add("car");  cacheNames.add("distributor");  ConcurrentHashMap<String, RedisCacheConfiguration> 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

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency>    <groupId>org.apache.commons</groupId>    <artifactId>commons-pool2</artifactId></dependency>

yml

#  redis配置spring:    redis:      database: 0      host: 127.0.0.1      password: 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);
@Configurationpublic 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";}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

【本文来自:台湾服务器 tw.html 复制请保留原URL】你在潮湿的风中感受到了平稳的呼吸,多好听啊,

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

相关文章:

你感兴趣的文章:

标签云: