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进行负载均衡,便能实现分布式的应用了。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTML5和CSS3强化知识总结

HTML5的新特性 HTML5的新增特性主要是针对于以前的不足&#xff0c;增一些新的标签、新的表单和新的表单属性等。这些新特性都有兼容性问题&#xff0c;基本是IE9以上版本的浏览器才支持&#xff0c;如果不考虑兼容性问题&#xff0c;可以大量使用这些新特性。 HTML5新增的语义…

linux实时调度

面对陌生的知识体系&#xff0c;应该从什么角度来 简介 一、进程管理基本概念 在单处理器系统上&#xff0c;在给定时刻只有一个程序可以运行&#xff0c;在多处理器系统上&#xff0c;可以真正并行运行的进程数据&#xff0c;取决于物理CPU的数目&#xff1b; 进程优先级 …

git 合并多条提交记录

我要合并多条提交记录&#xff08;合并前7条为一条&#xff09;&#xff0c;实现如下效果&#xff1a; 使用git rebase // 查看前10个commit git log -10 // 将7个commit压缩成一个commit&#xff1b;注意&#xff1a;vim编辑器 git rebase -i HEAD~4 // add已经跟踪的文件 g…

接口测试框架对比

公司计划系统的开展接口自动化测试&#xff0c;需要我这边调研一下主流的接口测试框架给后端测试&#xff08;主要测试接口&#xff09;的同事介绍一下每个框架的特定和使用方式。后端同事根据他们接口的特点提出一下需求&#xff0c;看哪个框架更适合我们。 需求 1、接口编写…

Linux 用户和权限

Linux 用户和权限 一、root 用户&#xff08;超级管理员&#xff09;1.su和exit命令2.sudo 命令3.为普通用户配置sudo认证 二、用户和用户组1.用户组管理2.用户管理3.getent 命令 三、查看权限控制信息1.认识权限控制信息 四、chmod命令五、chown命令 一、root 用户&#xff08…

怎样理解Vue单向数据流

在前端开发中&#xff0c;数据流是一个非常重要的概念。Vue.js作为一种流行的前端框架&#xff0c;采用了单向数据流的架构&#xff0c;旨在简化开发过程并提高应用的可维护性。本文将探讨Vue单向数据流的含义以及它的使用方法。 什么是单向数据流&#xff1f; 在Vue中&#…

天拓四方:边缘计算网关功能、特点与应用举例

传统的数据处理方式面临网络延迟、带宽限制和安全风险等问题。为了解决这些问题&#xff0c;边缘计算技术应运而生&#xff0c;而边缘计算网关作为其核心组件&#xff0c;正发挥着越来越重要的作用。边缘计算网关位于数据源和云数据中心之间。它具备数据采集、协议转换、数据处…

flask+vue+python跨区通勤人员健康体检预约管理系统

跨区通勤人员健康管理系统设计的目的是为用户提供体检项目等功能。 与其它应用程序相比&#xff0c;跨区通勤人员健康的设计主要面向于跨区通勤人员&#xff0c;旨在为管理员和用户提供一个跨区通勤人员健康管理系统。用户可以通过系统及时查看体检预约等。 跨区通勤人员健康管…

基于微信小程序的校园水电费管理小程序的研究与实现

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

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

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

web 技术栈有哪些?

前端技术栈&#xff1a; HTML&#xff08;超文本标记语言&#xff09;&#xff1a; 用于创建网页结构的标记语言&#xff0c;定义页面的内容和结构。 CSS&#xff08;层叠样式表&#xff09;&#xff1a; 用于设计和排版网页的样式表语言&#xff0c;负责页面的外观和样式。 …

Skywalking 应用笔记

概念 Skywalking是一款分布式的系统 性能监视工具&#xff0c;专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计。SkyWalking是一款 观察性的分析平台和应用性能管理系统&#xff0c;提供了 分布式追踪、性能指标分析、应用服务依赖分析、可视化一体化等解决方…

ChatGPT之制作短视频

引言 今天带来了如何使用 ChatGPT和剪映来制作简单的短视频教程&#xff0c;在这其中 ChatGPT的作用主要是帮我们生成文案&#xff0c;剪映的功能就是根据文案自动生成视频&#xff0c;并配上一些图片、动画、字幕和解说。 ChatGPT生成文案 首先&#xff0c;我们需要使用提示…

ChatGPT之搭建API代理服务

简介 一行Docker命令部署的 OpenAI/GPT API代理&#xff0c;支持SSE流式返回、腾讯云函数 。 项目地址&#xff1a;https://github.com/easychen/openai-api-proxy 这个项目可以自行搭建 OpenAI API 代理服务器工具&#xff0c;该项目是代理的服务器端&#xff0c;不是客户端。…

如何把vue项目打包成桌面程序 electron-builder

引入 我们想要把我们写的vue项目,打包成桌面程序&#xff0c;我们需要使用electron-builder这个库 如何使用 首先添加打包工具 vue add electron-builder 选择最新版本 下载完毕 我们可以看到我们的package.json中多了几行 electron:build&#xff1a;打包我们的可执行程序 e…

大白话介绍循环神经网络

循环神经网络实质为递归式的网络&#xff0c;它在处理时序任务表现出优良的效果&#xff0c;毕竟递归本来就是一步套一步的向下进行&#xff0c;而自然语言处理任务中涉及的文本天然满足这种时序性&#xff0c;比如我们写字就是从左到右一步步来的鸭&#xff0c;刚接触深度学习…

ACPF UI 框架设计与基础实现

世态人情,比明月清风更饶有滋味;可作书读,可当戏看。书上的描摹,戏里的扮演,即使栩栩如生,究竟只是文艺作品;人情世态,都是天真自然的流露,往往超出情理之外,新奇得令人震惊,令人骇怪,给人以更深刻的效益,更奇妙的娱乐。惟有身处卑微的人,最有机缘看到世态人情的…

【HTML 基础】元数据 meta 标签

文章目录 1. 设置字符集2. 描述网页内容3. 设置关键词4. 网页重定向5. 移动端优化注意事项结语 在网页开发中&#xff0c;<meta> 标签是一种十分重要的 HTML 元数据标签。通过巧妙使用 <meta> 标签&#xff0c;我们能够设置各种元数据&#xff0c;从而影响网页在浏…

Java21 + SpringBoot3集成七牛云对象存储OSS,实现文件上传

文章目录 前言实现步骤引入maven依赖修改配置文件创建七牛云配置类创建文件操作服务类创建文件操作控制器前端实现运行效果 总结 前言 近日心血来潮想做一个开源项目&#xff0c;目标是做一款可以适配多端、功能完备的模板工程&#xff0c;包含后台管理系统和前台系统&#xf…

flutter开发实战-可扩展popup弹窗template模版样式

flutter开发实战-可扩展popup弹窗template模版样式 最近在看到一个flutter_beautiful_popup&#xff0c;可以美化弹窗窗口样式。该插件通过一个template模版的类BeautifulPopupTemplate作为抽象的base类。 一、基类BeautifulPopupTemplate 在BeautifulPopupTemplate中&…