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));
        }
    }

Spring-Redis缓存业务优化(通配符删除、两种自定义缓存时长)的更多相关文章

  1. MySQL关闭查询缓存(QC)的两种方法

    MySQL Query Cache 会缓存select 查询,安装时默认是开启的,但是如果对表进行INSERT, UPDATE, DELETE, TRUNCATE, ALTER TABLE, DROP ...

  2. Redis安装、主从配置及两种高可用集群搭建

    Redis安装.主从配置及两种高可用集群搭建 一.            准备 Kali Linux虚拟机 三台:192.168.154.129.192.168.154.130.192.168.154 ...

  3. [leetcode]159. Longest Substring with At Most Two Distinct Characters至多包含两种字符的最长子串

    Given a string s , find the length of the longest substring t  that contains at most 2 distinct char ...

  4. Redis持久化存储(AOF与RDB两种模式)

    Redis中数据存储模式有2种:cache-only,persistence; cache-only即只做为“缓存”服务,不持久数据,数据在服务终止后将消失,此模式下也将不存在“数据恢复”的手段,是一 ...

  5. Guava的两种本地缓存策略

    Guava的两种缓存策略 缓存在很多场景下都需要使用,如果电商网站的商品类别的查询,订单查询,用户基本信息的查询等等,针对这种读多写少的业务,都可以考虑使用到缓存.在一般的缓存系统中,除了分布式缓存, ...

  6. 【Spring】SpringMVC非注解配置的两种方式

    目录结构: contents structure [+] SpringMVC是什么 Spring MVC的设计原理 SpringMVC配置的第一种方式 1,复制Jar包 2,Web.xml文件 3,M ...

  7. UWP开发中两种网络图片缓存方法

    通常情况下,我们的程序需要从服务器读取图片,但如果需要不止一次读取某一张图片的话,就需要做本地缓存了,这样既为用户省一点流量,又能显得你的APP很快. 假如你已经知道了某一张图片的地址,那么第一件事就 ...

  8. Spring Boot + Vue 前后端分离,两种文件上传方式总结

    在Vue.js 中,如果网络请求使用 axios ,并且使用了 ElementUI 库,那么一般来说,文件上传有两种不同的实现方案: 通过 Ajax 实现文件上传 通过 ElementUI 里边的 U ...

  9. spring boot 学习10 定义springboot的两种方法

    使用spring boot的两种方法: A:继承spring-boot-starter-parent项目 这种方式很简单,只需要在POM里面添加parent父工程即可. B: 如果你不喜欢继承spri ...

随机推荐

  1. Python+Selenium - 文件上传

    如下图,从系统点击上传功能,打开到这种如下图页面的才适合本文介绍的处理方法 处理方法一 pywinauto库 优点:可以选择多个文件,路径中有中文也支持 缺点:只能Windows平台使用 安装 pip ...

  2. Redis-内存优化(一)

    一.正确使用redis 数据类型 我们先了解下 String 类型的内存空间消耗问题,以及选择节省内存开销的数据类型的解决方案.例如一个图片存储系统,要求这个系统能快速地记录图片 ID 和图片在存储系 ...

  3. THINKPHP_(3)_TP6中实现多层关联,第一个表关联第二个表查询出的数据,再关联第三个表

    问题: (1)canxunDanwei数据表对应的模型中有一个关联是: public function canxunDanwei() { return $this->belongsTo('\ap ...

  4. 【Android编程】Java利用Socket类编写Metasploit安卓载荷辅助模块

    /作者:Kali_MG1937 CSDN博客:ALDYS4 QQ:3496925334/ 注意!此文章被作者标记到 黑历史 专栏中,这意味着本篇文章可能存在 质量低下,流水账文,笔法低质 的问题 为了 ...

  5. teprunner重磅更新Git打通PyCharm与测试平台

    经过Python测试交流群的小伙伴群策群力,teprunner添加了一个重要功能,把PyCharm中的代码,通过Git同步到测试平台中,生成测试用例.这样,teprunner就成了一个名副其实的pyt ...

  6. 【NX二次开发】获得屏幕矩阵并设置WCS为屏幕方向

    说明:获得屏幕矩阵并设置WCS为屏幕方向(Z朝向自己,X轴朝右,Y轴超上). 方法: 1 extern DllExport void ufusr(char *param, int *retcode, ...

  7. 消息队列面试题、RabbitMQ面试题、Kafka面试题、RocketMQ面试题 (史上最全、持续更新、吐血推荐)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  8. SpringBoot 结合 Spring Cache 操作 Redis 实现数据缓存

    系统环境: Redis 版本:5.0.7 SpringBoot 版本:2.2.2.RELEASE 参考地址: Redus 官方网址:https://redis.io/ 博文示例项目 Github 地址 ...

  9. 再有人问你HashMap,把这篇文章甩给他

    搞定HashMap 作为一个Java从业者,面试的时候肯定会被问到过HashMap,因为对于HashMap来说,可以说是Java==集合中的精髓==了,如果你觉得自己对它掌握的还不够好,我想今天这篇文 ...

  10. Java双重循环

    在实际开发中我们常常遇到这样的问题,有A.B两个集合,这两个集合的某一个字段是相同的,要把A集合和B进行匹配,然后把A的值赋值给B例如: //上传图片 List<MultipartFile> ...