• Spring-Redis缓存业务优化(通配符删除、两种自定义缓存时长)


    application.yml配置

    spring: 
      cache:
        type: REDIS
        redis:
          time-to-live: PT300S # 默认缓存秒数
          cache-null-values: false # 是否缓存空值

    支持指定cacheNames设置缓存时长

    /**
     * Redis配置类
     *
     * @author ZJJ
     */
    @Configuration
    @EnableConfigurationProperties(CacheProperties.class)
    public class RedisCacheConfig extends CachingConfigurerSupport {
        @Autowired
        private CacheProperties cacheProperties;

        @Autowired
        private RedisConnectionFactory redisConnectionFactory;

        @Bean
        @Primary
        public RedisTemplate<Serializable, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
            RedisTemplate<Serializable, Object> redisTemplate = new RedisTemplate<>();
            redisTemplate.setConnectionFactory(redisConnectionFactory);

            // 使用Jackson2JsonRedisSerialize 替换默认序列化
            Jackson2JsonRedisSerializer<Object> 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);

            // 设置value的序列化规则和 key的序列化规则
            redisTemplate.setDefaultSerializer(new StringRedisSerializer(StandardCharsets.UTF_8));// 默认为:JdkSerializeable
            redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
            redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);

            redisTemplate.afterPropertiesSet();
            return redisTemplate;
        }

        /**
         * 默认缓存管理器
         * <br>
         * 使用样例1:@Cacheable(cacheNames = "demoCache", key = "#id")// 5分钟
         * 使用样例2:@Cacheable(cacheNames = "userCache", key = "#id")// 默认10分钟
         * 使用样例3:@Cacheable(cacheNames = "customCache#60", key = "#id") // 自定义缓存60秒
         */
        @Override
        @Bean
        public RedisCacheManager cacheManager() {
            RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
                    .entryTtl(this.cacheProperties.getRedis().getTimeToLive());

            // 针对不同cacheName,设置不同的过期时间
            Map<String, RedisCacheConfiguration> initialCacheConfiguration = new LinkedHashMap<String, RedisCacheConfiguration>() {
                {
                    this.put("demoCache", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)));
                    // this.put("userCache", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(10))); // 10分钟
                    // TODO 其他自定义缓存时长...
                }
            };

            // return RedisCacheManager.builder(this.redisConnectionFactory).cacheDefaults(defaultCacheConfig)
            // .withInitialCacheConfigurations(initialCacheConfiguration).build();
            return new CustomRedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(this.redisConnectionFactory), defaultCacheConfig,
                    initialCacheConfiguration);
        }
    }

    /**
     * 自定义Redis缓存管理器 - 支持缓存名#缓存秒数
     *
     * @author ZJJ
     */
    class CustomRedisCacheManager extends RedisCacheManager {
        public CustomRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
            super(cacheWriter, defaultCacheConfiguration);
        }

        public CustomRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration,
                Map<String, RedisCacheConfiguration> initialCacheConfigurations) {
            super(cacheWriter, defaultCacheConfiguration, initialCacheConfigurations, true);
        }

        @Override
        protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
            String[] array = name.split("#");
            name = array[0];
            if (array.length > 1) { // 解析TTL
                cacheConfig = cacheConfig.entryTtl(Duration.ofSeconds(Long.parseLong(array[1]))); // 秒
            }
            return super.createRedisCache(name, cacheConfig);
        }
    }

    调整evict方法支持key通配符

    重写 org.springframework.data.redis.cache.RedisCache

        /*
         * 使用样例:@CacheEvict(cacheNames = "loginCache", key = "test-*")
         */
        @Override
        public void evict(Object key) {
            if (key instanceof String && ((String) key).endsWith("*")) {// 通配符删除
                byte[] pattern = this.conversionService.convert(this.createCacheKey(key), byte[].class);
                this.cacheWriter.clean(this.name, pattern);
            } else {// 单一key删除
                this.cacheWriter.remove(this.name, this.createAndConvertCacheKey(key));
            }
        }

  • 相关阅读:
    DataList控件部分使用方法
    评教系统——设计的重要性
    2010.7——2011.7年度总结
    Javascript初步
    asp.net天轰穿视频学习总结
    Datatable中对某列求和,三种不同情况下的方法
    DataTable删除多行
    C#语言的结构体布局
    geoserver、openlayers、PostgreSQL 开发环境配置
    字节流和结构体的转换[转]
  • 原文地址:https://www.cnblogs.com/zyrs/p/13653153.html
Copyright © 2020-2023  润新知