Redis——SpringBoot整合Redis实战

1、基本配置

1.1、引入依赖

首先,建立Maven项目,在Maven项目中引入pom.xml文件:

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

Jedis封装了Spring Boot与Redis的连接工具。

1.2、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= 

2、RedisTemplate API详解

Redis有5种不同的数据类型,这5种数据类型分别为String、List、Set、Hash和Sorted Set。Spring封装了RedisTemplate对象来对5种数据类型操作,它支持所有的Redis原生的API:

  • redisTemplate.opsForValue():操作String。
  • redisTemplate.opsForHash():操作Hash。
  • redisTemplate.opsForList():操作List。
  • redisTemplate.opsForSet():操作Set。
  • redisTemplate.opsForZSet():操作Sorted Set。

编写RedisService类,通过注解的方式调用RedisTemplate对象来操作Redis的5种数据类型。在RedisService类中使用了@Service注解来标注业务层,RedisService类将自动注入到Spring容器中。本实例使用“RedisService.java”,内容如下:

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.data.redis.core.*; 
import org.springframework.stereotype.Service; import java.io.Serializable; 
import java.util.List; 
import java.util.Set; 
import java.util.concurrent.TimeUnit; @Service 
public class RedisService { @Autowired private RedisTemplate redisTemplate; }

2.1、写入和读取缓存

在RedisService类中封装写入Redis缓存的业务逻辑的具体内容如下,使用redisTemplate.opsForValue()操作String:

public boolean set(final String key, Object value) { boolean result = false; try { ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); operations.set(key, value); result = true; } catch (Exception e) { e.printStackTrace(); } return result; 
} 

其中封装写入Redis缓存设置过期时间的业务逻辑的具体内容如下,需要调用redisTemplate.expire(key,expireTime,TimeUnit.SECONDS):

public boolean set(final String key, Object value, Long expireTime) { boolean result = false; try { ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); operations.set(key, value); redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); result = true; } catch (Exception e) { e.printStackTrace(); } return result; 
}

其中封装批量删除对应的key的业务逻辑的具体内容如下:

public void remove(final String... keys) { for (String key : keys) { remove(key); } 
} 

其中封装删除对应的key的业务逻辑的具体内容如下,需要调用redisTemplate.delete(key):

public void remove(final String key) { if (exists(key)) { redisTemplate.delete(key); } 
}

其中封装判断Redis缓存中是否有对应的key的业务逻辑的具体内容如下,需要调用redisTemplate.hasKey(key):

public boolean exists(final String key) { return redisTemplate.hasKey(key); 
} 

其中封装读取Redis缓存的业务逻辑的具体内容如下,使用redisTemplate.opsForValue()获得operations句柄,然后使用operations.get(key)获得Redis中对应的key的业务逻辑:

public Object get(final String key) { Object result = null; ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); result = operations.get(key); return result; 
}

2.2、添加和获取散列数据

在RedisService类中封装添加散列数据的业务逻辑的具体内容如下,使用redisTemplate.opsForHash()操作Hash:

public void hmSet(String key, Object hashKey, Object value) { HashOperations<String, Object, Object> hash = redisTemplate.opsForHash(); hash.put(key, hashKey, value); 
} 

封装获取散列数据的业务逻辑的具体内容如下,使用redisTemplate.opsForHash()获得hash句柄,然后使用hash.get(key,hashKey)获得key对应的Hash值:

public Object hmGet(String key, Object hashKey) { HashOperations<String, Object, Object> hash = redisTemplate.opsForHash(); return hash.get(key, hashKey); 
}

2.3、添加和获取列表数据

在RedisService类中封装添加列表数据的业务逻辑的具体内容如下,使用redisTemplate.opsForList()操作List:

public void lPush(String k, Object v) { ListOperations<String, Object> list = redisTemplate.opsForList(); list.rightPush(k, v); 
}

封装获取列表数据的业务逻辑的具体内容如下,使用redisTemplate.opsForList()获得list句柄,然后使用list.range(k,l,l1)获得Redis的列表数据:

public List<Object> lRange(String k, long l, long l1) { ListOperations<String, Object> list = redisTemplate.opsForList(); return list.range(k, l, l1); 
} 

2.4、添加和获取集合数据

在RedisService类中封装添加集合数据的业务逻辑的具体内容如下,使用redisTemplate.opsForSet()操作Set:

public void add(String key, Object value) { SetOperations<String, Object> set = redisTemplate.opsForSet(); set.add(key, value); 
}

封装获取集合数据的业务逻辑的具体内容如下,使用redisTemplate.opsForSet()获得SetOperations<String,Object>对象,然后使用set.members(key)获得Redis的集合数据:

public Set<Object> setMembers(String key) { SetOperations<String, Object> set = redisTemplate.opsForSet(); return set.members(key); 
}

2.5、添加和获取有序集合数据

在RedisService类中封装添加有序集合数据的业务逻辑的具体内容如下,使用redisTemplate.opsForZSet()操作Sorted Set:

public void zAdd(String key, Object value, double scoure) { ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();zset.add(key, value, scoure); 
}

封装获取有序集合数据的业务逻辑的具体内容如下,使用redisTemplate.opsForZSet()获得ZSetOperations<String,Object>对象,然后使用zset.rangeByScore(key,scoure,scoure1)获得Redis的有序集合数据:

public Set<Object> rangeByScore(String key, double scoure, double scoure1) { ZSetOperations<String, Object> zset = redisTemplate.opsForZSet(); redisTemplate.opsForValue(); return zset.rangeByScore(key, scoure, scoure1); 
}

3、Spring Boot集成Spring Session

传统Session的问题在于Session是由Web容器管理的,即一个Session只保存在一台服务器上,适合于单体应用。随着架构不断地向微服务分布式集群演进,传统的Session在集群环境下就不能正常工作了。例如,现在有3台Web服务器,客户端访问服务器通过负载均衡Nginx负载到某一台服务器上,用户此次的数据就保存到这台服务器的Web容器中了,如果用户下次请求被负载到其他服务器上,就获取不到之前保存的数据了。

这时候就需要整个服务器集群共享同一个Session。为了解决所有服务器共享一个Session的问题,Session就不能单独保存在自己的Web容器中,而是保存在一个公共的会话仓库(Session Repository)中,所有服务器都访问同一个会话仓库,这样所有服务器的状态都一致了。Spring Session支持的会话仓库有Redis、MongoDB、JDBC,本帖使用Redis作为Spring Session的会话仓库。

Spring Session有以下优点:

  • Spring Session是基于Servlet规范实现的一套Session管理框架。Spring Session主要解决了分布式场景下Session的共享问题。Spring Session最核心的类是SessionRepositoryFilter,用于包装用户的请求和响应。
  • 可在程序中直接替换HttpSession,而无须修改一行代码。
  • 可以很方便地与Spring Security集成,增加诸如findSessionsByUserName、rememberMe,限制同一个账号可以同时在线的Session数(例如设置成1,即可达到把前一次登录替换的效果)等。

3.1、配置Spring Boot项目

在Maven项目的pom.xml文件里引入必要的依赖包:

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

配置文件application.properties,内容如下:

# Redis 配置 
# Redis数据库索引(默认为0) 
spring.redis.database=0 
# Redis服务器地址 
spring.redis.host=127.0.0.1 
# Redis服务器连接端口 
spring.redis.port=6379 
# Redis服务器连接密码(默认为空) 
spring.redis.password=

3.2、创建配置类和控制器类

创建配置类RedisHttpSessionConfiguration,本实例使用“Configuration.java”,内容如下:

 
import org.springframework.context.annotation.Configuration; 
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; @Configuration 
//maxInactiveIntervalInSeconds默认是1800s过期,这里测试修改为60s 
@EnableRedisHttpSession(maxInactiveIntervalInSeconds=60) 
public class RedisHttpSessionConfiguration { }

配置类RedisHttpSessionConfiguration使用@Configuration注解表明这是一个配置类。在这个类中也添加了注解@EnableRedisHttpSession,表示开启Redis的Session管理。如果需要设置会话失效时间,可以使用@EnableRedisHttpSession(maxInactiveIntervalInSeconds=60)表示在60秒后会话失效。

创建用户类User,用户类只有两个属性username和password,保存用户登录的用户名和密码。本实例使用“User.java”,内容如下:

  
import java.io.Serializable; public class User implements Serializable{ private String name; private String password; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", password='" + password + '\'' + '}'; } 
}

创建控制器类SessionController,在这个类中定义了2个方法。login方法用于登录验证,当输入username等于“xinping”,password等于“123”,判断用户登录成功,在Session中保存用户信息。get方法用于从Session中获取用户信息。本实例使用“SessionController.java”,内容如下:

package com.dxtd.SpringSessionDemo.controller; import org.springframework.web.bind.annotation.*; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpSession; 
import java.util.HashMap; 
import java.util.Map; @RestController 
public class SessionController {/** * 登录系统 *     * */ @RequestMapping(value="/session/login", method = RequestMethod.GET) @ResponseBody public Map login(@RequestParam("username") String username,@RequestParam
("password") String password,HttpServletRequest request, HttpSession session) { String message = "login failure"; Map<String, Object> result = new HashMap<String, Object>(); if(username != null && "xinping".equals(username) && "123".equals
(password)){ User user = new User(); user.setName(username); user.setPassword(password); request.getSession().setAttribute("admin", user); message = "login success"; result.put("message" , message); result.put("sessionId",session.getId()); }else{ result.put("message" , message); } return result; } /** * 查询用户 *    * */ @RequestMapping(value="/session/get", method = RequestMethod.GET) @ResponseBody public Map get(@RequestParam("username") String username,HttpServletRequest 
request, HttpSession session) { Object value = request.getSession().getAttribute("admin"); Map<String,Object> result = new HashMap<String,Object>(); result.put("message" ,value); result.put("sessionId",session.getId()); return result; } }

3.3、项目验证

启动项目,运行SpringSessionDemoApplication.java,进入SpringSessionDemo项目所在目录:

D:\quant\Redis\Chapter08\SpringSessionDemo>mvn clean package

在SpringSessionDemo\target目录下获得编译好的压缩包SpringSessionDemo-0.0.1-SNAPSHOT.jar,如下图所示:
在这里插入图片描述
使用如下命令分别以两个不同的端口(8081和8082)启动项目,用于模拟分布式应用中的两个服务:

java -jar SpringSessionDemo-0.0.1-SNAPSHOT.jar --server.port=8081 
java -jar SpringSessionDemo-0.0.1-SNAPSHOT.jar --server.port=8082

启动项目,如下图所示:
在这里插入图片描述
第1步:访问http://127.0.0.1:8081/session/login?username=xinping&password=123。第一次访问URL地址端口为8081的Spring Boot项目时模拟用户登录,在浏览器中访问这个请求后的结果如下图所示:
在这里插入图片描述
第2步:访问地址http://127.0.0.1:8082/session/get?username=xinping。第二次访问URL地址端口为8082的Spring Boot项目时模拟获取登录的用户信息,在浏览器中访问这个请求后的结果如下图所示:
在这里插入图片描述
可以看出成功获取了保存在Redis中的用户名为xinping的用户信息,并且两次请求的Session ID是相同的,实现了Session的共享。

通过Spring Boot使用Redis来实现Session的共享很方便,再配合Nginx进行负载均衡,便能实现分布式的应用了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/667497.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络_1.6.3 计算机网络体系结构分层思想举例

1.6.3 计算机网络体系结构分层思想举例 1、实例引入&#xff08;用户在主机中使用浏览器访问web服务器&#xff09;2、从五层原理体系结构的角度研究该实例3、练习题 笔记来源&#xff1a; B站 《深入浅出计算机网络》课程 本节通过一个常见的网络应用实例&#xff0c;来介绍计…

灵活应对:策略模式在软件设计中的应用

策略模式是一种行为型设计模式&#xff0c;它允许定义一系列算法&#xff0c;并将每个算法封装起来&#xff0c;使它们可以互换使用。策略模式让算法的变化独立于使用算法的客户端&#xff0c;使得在不修改原有代码的情况下切换或扩展新的算法成为可能。 使用策略模式的场景包…

android inset 管理

目录 简介 Insets管理架构 Insets相关类图 app侧的类 WMS侧的类 inset show的流程 接口 流程 WMS侧确定InsetsSourceControl的流程 两个问题 窗口显示时不改变现有的inset状态 全屏窗口上的dialog 不显示statusbar问题 View 和 DecorView 设置insets信息 输入法显…

幻兽帕鲁客户端存档文件 - 云上备份和恢复教程

本文将详细介绍如何将幻兽帕鲁游戏客户端的存档文件备份至云端&#xff0c;以及如何从云端恢复存档数据至本地。 一、游戏存档备份场景 幻兽帕鲁的游戏进度存储在电脑本地磁盘上&#xff0c;游戏中创建的每个世界都对应一个本地存档文件夹。在玩游戏过程中&#xff0c;客户端…

智能边缘计算网关实现高效数据处理与实时响应-天拓四方

在当今时代&#xff0c;数据已经成为驱动业务决策的关键因素。然而&#xff0c;传统的数据处理方式往往存在延迟&#xff0c;无法满足实时性要求。此时&#xff0c;智能边缘计算网关应运而生&#xff0c;它能够将数据处理和分析的能力从中心服务器转移至设备边缘&#xff0c;大…

基于单片机控制的智能门锁设计

摘要&#xff1a;阐述基于STC15F2K60S2单片机控制的智能门锁设计&#xff0c;包括CPU控制单元模块、液晶显示LCD、 Wi-Fi模块&#xff0c;实现远程控制开门&#xff0c;密码开门的智能化功能。 关键词&#xff1a;控制技术&#xff0c;单片机&#xff0c;智能门锁&#xff0c;…

游戏视频录制软件推荐,打造专业电竞视频(3款)

随着游戏产业的快速发展&#xff0c;越来越多的玩家开始关注游戏视频录制软件。一款好的录制软件不仅可以帮助玩家记录游戏中的精彩瞬间&#xff0c;还可以让其与他人分享自己的游戏体验。接下来&#xff0c;我们将介绍三款热门的游戏视频录制软件&#xff0c;并对其进行详细的…

收放卷转动线速度计算FC(SCL+梯形图代码)

这篇博客是收放控制算法的基础系列,通过这篇文章的学习。大家能更好的理解收放卷控制里的前馈量计算,收放卷前馈PID大家可以参考下面链接文章: https://rxxw-control.blog.csdn.net/article/details/129352629https://rxxw-control.blog.csdn.net/article/details/12935262…

3D Line Mapping Revisited论文阅读

1. 代码地址 GitHub - cvg/limap: A toolbox for mapping and localization with line features. 2. 项目主页 3D Line Mapping Revisited 3. 摘要 提出了一种基于线的重建算法&#xff0c;Limap&#xff0c;可以从多视图图像中构建3D线地图&#xff0c;通过线三角化、精心…

06、全文检索 -- Solr -- Solr 全文检索之在图形界面管理 Core 的 Schema(演示对 普通字段、动态字段、拷贝字段 的添加和删除)

目录 Solr 全文检索之管理 Schema使用Web控制台管理Core的Schema3 种 字段解释&#xff1a;Field&#xff1a;普通字段Dynamic Field&#xff1a;动态字段Copy Field&#xff1a;拷贝字段 演示&#xff1a;添加 普通字段&#xff08; Field &#xff09;演示&#xff1a;添加 动…

C++入门的基础

幸福比傲慢更容易蒙住人的眼睛。 ——大仲马 C入门 1、属于C的关键字1、1、C从何而来1、2、C关键字(C98) 2、命名空间2、1、命名空间的定义2、2、命名空间使用 3、C输入和输出4、缺省参数4、1、缺省参数概念4、2、缺省参数分类 5、函数重载5、1、函数重载概念 6、引用6、1、引用…

电脑/机顶盒/ps3/4/连接老电视(只有AV、S-Video接口)解决方案之HDMI转AV/S-Video转换器HAV

HDMI转AV/S-Video转换器功能 01、将HDMI高清信号经过视频处理转换成AV、S-VIDEO(PAL/NTSC)的视频信号输出 02、将HDMI数字音频&#xff0c;经过DAC数模芯片处理转成模拟立体声输出 03、采用先进的视频处理技术&#xff0c;对图像的亮度&#xff0c;对比度及色彩进行增强处理 04…

使用Docker本地部署Jupyter Notebook并结合内网穿透实现远程访问

文章目录 1. 选择与拉取镜像2. 创建容器3. 访问Jupyter工作台4. 远程访问Jupyter工作台4.1 内网穿透工具安装4.2 创建远程连接公网地址4.3 使用固定二级子域名地址远程访问 本文主要介绍如何在Ubuntu系统中使用Docker本地部署Jupyter Notebook&#xff0c;并结合cpolar内网穿透…

01-操作系统_名词_文件下载_反弹

操作系统_名词_文件下载_反弹 一、渗透测试1.1、POC、EXP、Payload与Shellcode1.2、后门1.3、木马1.4、反弹1.5、回显1.6、跳板1.7、黑白盒测试1.8、暴力破解1.9、社会工程学1.10、撞库1.11、ATT&CK 二、案例演示2.1、基础案例1&#xff1a;操作系统-用途&命令&权限…

Android学习之路(27) ProGuard,混淆,R8优化

前言 使用java编写的源代码编译后生成了对于的class文件&#xff0c;但是class文件是一个非常标准的文件&#xff0c;市面上很多软件都可以对class文件进行反编译&#xff0c;为了我们app的安全性&#xff0c;就需要使用到Android代码混淆这一功能。 针对 Java 的混淆&#x…

【Docker】Docker Registry(镜像仓库)

文章目录 一、什么是 Docker Registry二、镜像仓库分类三、镜像仓库工作机制四、常用的镜像仓库五、常用命令镜像仓库命令镜像命令(部分)容器命令(部分) 六、docker镜像仓库实战综合实战一&#xff1a;搭建一个 nginx 服务综合实战二&#xff1a;Docker hub上创建自己私有仓库综…

B站课程评分

Spring6 https://www.bilibili.com/video/BV1Ft4y1g7Fb/ 评价: 推荐一看 配套文档优秀, 老师口齿清晰, 条理不错. mybatis https://www.bilibili.com/video/BV1JP4y1Z73S/?spm_id_from333.337.search-card.all.click 评价: 推荐一看 配套文档优秀, 老师口齿清晰, 条理不错…

等变和不变 、向量神经元(vector neurons)是什么?

等变和不变 等变&#xff1a;如果输入是一个旋转后的椅子&#xff0c;那么输出也应该是一个旋转后的椅子 不变&#xff1a;如果输入是一个旋转后的椅子&#xff0c;那么输出应该是一个椅子&#xff0c;而不是一只狗。 向量神经元&#xff08;vector neurons&#xff09; 向量…

如何监控摄像头是否在线?有什么工具推荐

WGCLOUD监控系统 我们项目中&#xff0c;摄像头用的WGCLOUD监控系统来监控的&#xff0c;主要两种方式来监控 一种是监控摄像头的端口&#xff0c;使用WGCLOUD的端口监控模块 一种是PING摄像头的IP&#xff0c;使用WGCLOUD的ping监测模块 这两种方式比较简单&#xff0c;也…

1997-2022年中央对各省份一般公共预算转移支付数据

1997-2022年中央对各省份一般公共预算转移支付数据 1、时间&#xff1a;1997-2022年 2、范围&#xff1a;31省 3、指标&#xff1a;一般公共预算转移支付 4、来源&#xff1a;wind 财政部 5、指标解释&#xff1a;一般性转移支付又称体制性转移支付&#xff0c;是指上级政…