[Springboot]SpringCache + Redis实现数据缓存

简介: 本文实现了SpringCache + Redis的集中式缓存,方便大家对学习了解缓存的使用。本文实现:SpringCache + Redis的组合通过配置文件实现了自定义key过期时间;key命名方式;value序列化方式实现本文代码的前提:已有一个可以运行的Springboot项目,实现了简单的CRUD功能


前言



本文实现了SpringCache + Redis的集中式缓存,方便大家对学习了解缓存的使用。

本文实现:

  • SpringCache + Redis的组合
  • 通过配置文件实现了自定义key过期时间;key命名方式;value序列化方式

实现本文代码的前提:

  • 已有一个可以运行的Springboot项目,实现了简单的CRUD功能


步骤


在Spring Boot中通过@EnableCaching注解自动化配置合适的缓存管理器(CacheManager),Spring Boot根据下面的顺序去侦测缓存提供者:

Generic
JCache (JSR-107)
EhCache 2.x
Hazelcast
Infinispan
Redis
Guava
Simple
复制代码

我们所需要做的就是实现一个将缓存数据放在Redis的缓存机制。

  • 添加pom.xml依赖
<!-- 缓存: spring cache -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
  </dependency>
  <!-- 缓存: redis -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
  </dependency>
复制代码

注意:- spring-boot-starter-data-redis和spring-boot-starter-redis的区别:blog.csdn.net/weixin_3852…

可以看出两个包并没有区别,但是当springBoot的版本为1.4.7 以上的时候,spring-boot-starter-redis 就空了。要想引入redis就只能选择有data的。

  • application.properties中加入redis连接设置(其它详细设置请查看参考网页)
# Redis
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.database=0
spring.redis.password=xxx
复制代码
  • 新增KeyGeneratorCacheConfig.java(或者名为CacheConfig)文件

该文件完成三项设置:key过期时间;key命名方式;value序列化方式:JSON便于查看

package com.pricemonitor.pm_backend;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.lang.reflect.Method;
@Configuration
public class KeyGeneratorCacheConfig extends CachingConfigurerSupport {
    private final RedisTemplate redisTemplate;
    @Autowired
    public KeyGeneratorCacheConfig(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    @Override
    public CacheManager cacheManager() {
        // 设置key的序列化方式为String
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // 设置value的序列化方式为JSON
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        // 设置默认过期时间为600秒
        cacheManager.setDefaultExpiration(600);
        return cacheManager;
    }
    /**
     * key值为className+methodName+参数值列表
     * @return
     */
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object o, Method method, Object... args) {
                StringBuilder sb = new StringBuilder();
                sb.append(o.getClass().getName()).append("#");
                sb.append(method.getName()).append("(");
                for (Object obj : args) {
                    if(obj != null) { // 在可选参数未给出时时,会出现null,此时需要跳过
                        sb.append(obj.toString()).append(",");
                    }
                }
                sb.append(")");
                return sb.toString();
            }
        };
    }
}
复制代码
  • 在serviceImpl中加入@CacheConfig并且给给每个方法加入缓存(详细注解使用请查看参考网页)
@Service
@CacheConfig(cacheNames = "constant")
public class ConstantServiceImpl implements ConstantService {
    @Autowired
    private ConstantMapper constantMapper;
    @Cacheable
    @Override
    public List<Constant> alertMessage() {
        ConstantExample constantExample = new ConstantExample();
        ConstantExample.Criteria criteria = constantExample.createCriteria();
        criteria.andTypeEqualTo("alert");
        return constantMapper.selectByExample(constantExample);
    }
    @Cacheable
    @Override
    public List<Constant> noteMessage() {
        ConstantExample constantExample = new ConstantExample();
        ConstantExample.Criteria criteria = constantExample.createCriteria();
        criteria.andTypeEqualTo("note");
        return constantMapper.selectByExample(constantExample);
    }
    @Cacheable
    @Override
    public List<Constant> banner() {
        ConstantExample constantExample = new ConstantExample();
        ConstantExample.Criteria criteria = constantExample.createCriteria();
        criteria.andTypeEqualTo("banner");
        return constantMapper.selectByExample(constantExample);
    }
}
复制代码


效果图



注意事项


  • 若直接修改数据库的表,并没有提供接口修改的字段,缓存就没法更新。所以这种字段加缓存需要尤其注意缓存的有效性,最好让其及时过期。或者给其实现增删改接口。
  • 大坑:在可选参数未给出时时,会出现null,此时在生成Key名的时候需要跳过。已在代码中修改
for (Object obj : args) {
    if(obj != null) { // 在可选参数未给出时时,会出现null,此时需要跳过
        sb.append(obj.toString()).append(",");
    }
}


相关文章
|
Web App开发 存储 缓存
如何精准清除特定类型或标签的缓存数据?
如何精准清除特定类型或标签的缓存数据?
1080 57
|
缓存 负载均衡 监控
135_负载均衡:Redis缓存 - 提高缓存命中率的配置与最佳实践
在现代大型语言模型(LLM)部署架构中,缓存系统扮演着至关重要的角色。随着LLM应用规模的不断扩大和用户需求的持续增长,如何构建高效、可靠的缓存架构成为系统性能优化的核心挑战。Redis作为业界领先的内存数据库,因其高性能、丰富的数据结构和灵活的配置选项,已成为LLM部署中首选的缓存解决方案。
1085 25
|
12月前
|
NoSQL Java 网络安全
SpringBoot启动时连接Redis报错:ERR This instance has cluster support disabled - 如何解决?
通过以上步骤一般可以解决由于配置不匹配造成的连接错误。在调试问题时,一定要确保服务端和客户端的Redis配置保持同步一致。这能够确保SpringBoot应用顺利连接到正确配置的Redis服务,无论是单机模式还是集群模式。
853 5
|
存储 缓存 NoSQL
Redis专题-实战篇二-商户查询缓存
本文介绍了缓存的基本概念、应用场景及实现方式,涵盖Redis缓存设计、缓存更新策略、缓存穿透问题及其解决方案。重点讲解了缓存空对象与布隆过滤器的使用,并通过代码示例演示了商铺查询的缓存优化实践。
502 1
Redis专题-实战篇二-商户查询缓存
|
NoSQL Java 调度
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
分布式锁是分布式系统中用于同步多节点访问共享资源的机制,防止并发操作带来的冲突。本文介绍了基于Spring Boot和Redis实现分布式锁的技术方案,涵盖锁的获取与释放、Redis配置、服务调度及多实例运行等内容,通过Docker Compose搭建环境,验证了锁的有效性与互斥特性。
1047 0
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
|
缓存 运维 监控
Redis 7.0 高性能缓存架构设计与优化
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Redis 7.0高性能缓存架构,探索函数化编程、多层缓存、集群优化与分片消息系统,用代码在二进制星河中谱写极客诗篇。
2047 3
|
缓存 NoSQL 关系型数据库
Redis缓存和分布式锁
Redis 是一种高性能的键值存储系统,广泛用于缓存、消息队列和内存数据库。其典型应用包括缓解关系型数据库压力,通过缓存热点数据提高查询效率,支持高并发访问。此外,Redis 还可用于实现分布式锁,解决分布式系统中的资源竞争问题。文章还探讨了缓存的更新策略、缓存穿透与雪崩的解决方案,以及 Redlock 算法等关键技术。
|
存储 缓存 监控
一次缓存引发的文件系统数据不一致问题排查与深度解析
本文详述了一次由自研分布式文件系统客户端 EFC 的缓存架构更新所引发的严重数据不一致问题的完整排查过程。
一次缓存引发的文件系统数据不一致问题排查与深度解析
|
JSON Java 数据格式
Spring Boot返回Json数据及数据封装
在Spring Boot中,接口间及前后端的数据传输通常使用JSON格式。通过@RestController注解,可轻松实现Controller返回JSON数据。该注解是Spring Boot新增的组合注解,结合了@Controller和@ResponseBody的功能,默认将返回值转换为JSON格式。Spring Boot底层默认采用Jackson作为JSON解析框架,并通过spring-boot-starter-json依赖集成了相关库,包括jackson-databind、jackson-datatype-jdk8等常用模块,简化了开发者对依赖的手动管理。
961 3
|
机器学习/深度学习 数据采集 人机交互
springboot+redis互联网医院智能导诊系统源码,基于医疗大模型、知识图谱、人机交互方式实现
智能导诊系统基于医疗大模型、知识图谱与人机交互技术,解决患者“知症不知病”“挂错号”等问题。通过多模态交互(语音、文字、图片等)收集病情信息,结合医学知识图谱和深度推理,实现精准的科室推荐和分级诊疗引导。系统支持基于规则模板和数据模型两种开发原理:前者依赖人工设定症状-科室规则,后者通过机器学习或深度学习分析问诊数据。其特点包括快速病情收集、智能病症关联推理、最佳就医推荐、分级导流以及与院内平台联动,提升患者就诊效率和服务体验。技术架构采用 SpringBoot+Redis+MyBatis Plus+MySQL+RocketMQ,确保高效稳定运行。
1060 0