【小家Spring】Spring Boot中使用RedisTemplate优雅的操作Redis,并且解决RedisTemplate泛型注入失败的问题(上)

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 【小家Spring】Spring Boot中使用RedisTemplate优雅的操作Redis,并且解决RedisTemplate泛型注入失败的问题(上)

前言


Spring为了简化我们对持久化层的操作,针对各种持久化方案提供了统一的Template进行操作。比如我们的熟悉的JdbcTemplate就是让我们方便的操作的关系型数据库的。


它有个Spring-Data的子项目,提供了各种SQL、NOSql的便捷操作。比如Redis、MongoDB、ES等等。然后本文主要针对于在SpringBoot中使用RedisTemplate来优雅的操作Redis数据库


虽然我们已经有了强大的缓存注解如:@Cacheable、@CachePut、@CacheEvict等。但是面对稍微复杂点的场景,一个注解是搞不定的


推荐阅读:【小家Spring】细说Spring IOC容器的自动装配(@Autowired),以及Spring4.0新特性之【泛型依赖注入】的源码级解析

先理解泛型依赖注入的原理,再去读下文注入失败问题,很多问题都会迎刃而解~


在Spring中缓存主要有一个缓存接口(Cache)与缓存管理接口(CacheManager)。可以通过扩展这两个接口实现对应的缓存管理。


image.png



关于Spring-data-redis


SpringBoot提供了关于redis的启动器:spring-boot-starter-data-redis内部实际依赖于Spring的子项目:Spring-data-redis。因此我们先了解下,这个子项目到底做了些什么呢?


1。连接池自动管理,提供了一个高度封装的“RedisTemplate”类


此处指的连接池不一定是JedisPool,因为SpringBoot2.0之后,底层默认不再采用Jedis作为实现了。而是采用效率更高,线程更安全的lettuce客户端


2.针对jedis客户端(或者是lettuce)中大量api进行了归类封装,将同一类型操作封装为operation接口


ValueOperations:简单K-V操作

SetOperations:set类型数据操作

ZSetOperations:zset类型数据操作

HashOperations:针对map类型的数据操作

ListOperations:针对list类型的数据操作


3.提供了对key的“bound”(绑定)便捷化操作API,可以通过bound封装指定的key,然后进行一系列的操作而无须“显式”的再次指定Key,即BoundKeyOperations:


BoundValueOperations

BoundSetOperations

BoundListOperations

BoundSetOperations

BoundHashOperations


(其实底层就是个装饰器,对上面进行了装饰而已。。。但使用起来有时候还是方便了很多的)


BoundSetOperations<String, Long> boundSetOperations = redisTemplate.boundSetOps("aaa");
//然后其余的操作方式,和SetOperations一样
//所以如果你的key是不变的,使用它更方便且效率更高。但如果你的key是变的(比如有用户id参数),那使用它就不是很方便了


特别指出的是:虽然BoundSetOperations只是包了一层,但Spring对隐藏实现确实做得非常不错。BoundSetOperations接口的默认实现类DefaultBoundSetOperations不是public的,只有Default的,所以外界根本不能访问,完全隐藏了实现。这一点在我们自己设计框架的时候,还是值得学习的

4.将事务操作封装,由容器控制。


5.针对数据的“序列化/反序列化”,提供了多种可选择策略(RedisSerializer)(RedisTemplate的序列化方式其实有很多坑,下面博文已详细介绍)


JdkSerializationRedisSerializer:POJO对象的存取场景,使用JDK本身序列化机制(所以必须实现序列化接口),将pojo类通过ObjectInputStream/ObjectOutputStream进行序列化操作,最终redis-server中将存储字节序列。是目前最常用的序列化策略。

StringRedisSerializer:Key或者value为字符串的场景,根据指定的charset对数据的字节序列编码成string,是“new String(bytes, charset)”和“string.getBytes(charset)”的直接封装。是最轻量级和高效的策略。

【小家Spring】RedisTemplate的序列化方式大解读,含FastJsonRedisSerializer、Genericjackson2jsonredisserializer序列化的坑

.

.

.


在SpringBoot中的使用(整合)


如果是在单纯的Spring环境下使用,可能还会有一些配置的活。但在Boot环境下,简直不要太方便


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


然后加上对应的连接配置:application.properties


# Redis数据库索引(默认为0)
spring.redis.database=0  
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379  
# Redis服务器连接密码(默认为空)
spring.redis.password=
##############下面参数一般可选,但我建议配置,更加可控###################
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8  
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1  
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8  
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0  
# 连接超时时间(毫秒)
spring.redis.timeout=0


就这么简单,完美了。看看demo


    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Test
    public void contextLoads() {
        System.out.println(redisTemplate); //org.springframework.data.redis.core.StringRedisTemplate@4d354a3e
    }


RedisTemplate的注入问题


看到上面的demo,大家是否疑问:为什么我什么都没做。就能够@Autowired注入RedisTemplate呢?


用了SpringBoot,一切都变得简单。看看对应的自动配置类:一目了然


  @Bean
  @ConditionalOnMissingBean(name = "redisTemplate")
  public RedisTemplate<Object, Object> redisTemplate(
      RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
    RedisTemplate<Object, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
  }
  @Bean
  @ConditionalOnMissingBean
  public StringRedisTemplate stringRedisTemplate(
      RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
    StringRedisTemplate template = new StringRedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
  }


所以很显然,Boot默认为我们自动注入了两个Bean,因此我们也能实现自动注入。


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
8天前
|
缓存 安全 Java
Spring Boot 3 集成 Spring Security + JWT
本文详细介绍了如何使用Spring Boot 3和Spring Security集成JWT,实现前后端分离的安全认证概述了从入门到引入数据库,再到使用JWT的完整流程。列举了项目中用到的关键依赖,如MyBatis-Plus、Hutool等。简要提及了系统配置表、部门表、字典表等表结构。使用Hutool-jwt工具类进行JWT校验。配置忽略路径、禁用CSRF、添加JWT校验过滤器等。实现登录接口,返回token等信息。
155 12
|
14天前
|
存储 安全 Java
Spring Boot 3 集成Spring AOP实现系统日志记录
本文介绍了如何在Spring Boot 3中集成Spring AOP实现系统日志记录功能。通过定义`SysLog`注解和配置相应的AOP切面,可以在方法执行前后自动记录日志信息,包括操作的开始时间、结束时间、请求参数、返回结果、异常信息等,并将这些信息保存到数据库中。此外,还使用了`ThreadLocal`变量来存储每个线程独立的日志数据,确保线程安全。文中还展示了项目实战中的部分代码片段,以及基于Spring Boot 3 + Vue 3构建的快速开发框架的简介与内置功能列表。此框架结合了当前主流技术栈,提供了用户管理、权限控制、接口文档自动生成等多项实用特性。
60 8
|
1月前
|
负载均衡 Java 开发者
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
175 5
|
3月前
|
NoSQL Java Redis
redis的基本命令,并用netty操作redis(不使用springboot或者spring框架)就单纯的用netty搞。
这篇文章介绍了Redis的基本命令,并展示了如何使用Netty框架直接与Redis服务器进行通信,包括设置Netty客户端、编写处理程序以及初始化Channel的完整示例代码。
92 1
redis的基本命令,并用netty操作redis(不使用springboot或者spring框架)就单纯的用netty搞。
|
4月前
|
JSON NoSQL Java
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
这篇文章介绍了在Java中使用Redis客户端的几种方法,包括Jedis、SpringDataRedis和SpringBoot整合Redis的操作。文章详细解释了Jedis的基本使用步骤,Jedis连接池的创建和使用,以及在SpringBoot项目中如何配置和使用RedisTemplate和StringRedisTemplate。此外,还探讨了RedisTemplate序列化的两种实践方案,包括默认的JDK序列化和自定义的JSON序列化,以及StringRedisTemplate的使用,它要求键和值都必须是String类型。
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
|
3月前
|
Java 测试技术 开发者
springboot学习四:Spring Boot profile多环境配置、devtools热部署
这篇文章主要介绍了如何在Spring Boot中进行多环境配置以及如何整合DevTools实现热部署,以提高开发效率。
131 2
|
3月前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
424 1
|
3月前
|
Java API Spring
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。
49 0
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
|
3月前
|
Java API Spring
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中过滤器的基础知识和实战项目应用的教程。
54 0
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
|
3月前
|
Java 测试技术 Spring
springboot学习三:Spring Boot 配置文件语法、静态工具类读取配置文件、静态工具类读取配置文件
这篇文章介绍了Spring Boot中配置文件的语法、如何读取配置文件以及如何通过静态工具类读取配置文件。
277 0
springboot学习三:Spring Boot 配置文件语法、静态工具类读取配置文件、静态工具类读取配置文件