Redis是一个开源免费的高性能key-value数据库,读取速度达110000次/s,写入速度达81000次/s。Redis支持丰富的数据类型,如Lists, Hashes, Sets 及 Ordered Sets 数据类型。Redis的所有操作都是原子性的,要么成功执行要么失败完全不执行。另外还可以通过MULTI和EXEC指令包起来支持事务。此外,Redis还具备丰富的特性 ,比如支持发布/订阅(publish/subscribe)模式,可以充当简单的消息中间件,还支持通知, key过期设置主从复制等等特性。

Redis主要以下三个特点:

1.支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。

2.支持丰富的数据类型,除了支持简单的key-value类型,同时还提供list,set,zset,hash等数据结构的存储。

3.支持数据的备份,即主从(master-slave)模式模式的数据备份。

接下来,我们就用一个简单的案例来说明在Spring Boot中如何使用Redis技术。

首先,需要安装Redis,教程很多,这里不再赘述。可以参考:Redis安装教程

为方便我们初始化项目,Spring Boot给我们提供一个项目模板生成网站。

1.  打开浏览器,访问:https://start.spring.io/

2.  根据页面提示,选择构建工具,开发语言,项目信息等。

3.  点击 Generate the project,生成项目模板,生成之后会将压缩包下载到本地。

4.  使用IDE导入项目,我这里使用Eclipse,通过导入Maven项目的方式导入。

清理掉不需要的测试类及测试依赖,添加 Redis相关依赖。

  1. <!-- spring boot redis -->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-data-redis</artifactId>
  5. </dependency>
  6. <!-- lettuce pool -->
  7. <dependency>
  8. <groupId>org.apache.commons</groupId>
  9. <artifactId>commons-pool2</artifactId>
  10. </dependency>

Spring Boot框架中已经集成了redis,在1.x.x的版本中默认使用jedis客户端,而在2.x.x版本中默认使用的lettuce客户端。

两种客户端的区别如下:

  • Jedis和Lettuce都是Redis Client
  • Jedis 是直连模式,在多个线程间共享一个 Jedis 实例时是线程不安全的,
  • 如果想要在多线程环境下使用 Jedis,需要使用连接池,
  • 每个线程都去拿自己的 Jedis 实例,当连接数量增多时,物理连接成本就较高了。
  • Lettuce的连接是基于Netty的,连接实例可以在多个线程间共享,
  • 所以,一个多线程的应用可以使用同一个连接实例,而不用担心并发线程的数量。
  • 当然这个也是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。
  • 通过异步的方式可以让我们更好的利用系统资源,而不用浪费线程等待网络或磁盘I/O。
  • Lettuce 是基于 netty 的,netty 是一个多线程、事件驱动的 I/O 框架,
  • 所以 Lettuce 可以帮助我们充分利用异步的优势。

我的项目是使用的是Spring Boot 2.1.5.RELEASE,所以采用lettuce来进行配置。

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.1.5.RELEASE</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.louis.springboot</groupId>
  12. <artifactId>demo</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>demo</name>
  15. <description>Demo project for Spring Boot</description>
  16.  
  17. <properties>
  18. <java.version>1.8</java.version>
  19. </properties>
  20.  
  21. <dependencies>
  22. <dependency>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-starter</artifactId>
  25. </dependency>
  26. <!-- web -->
  27. <dependency>
  28. <groupId>org.springframework.boot</groupId>
  29. <artifactId>spring-boot-starter-web</artifactId>
  30. </dependency>
  31. <!-- swagger -->
  32. <dependency>
  33. <groupId>io.springfox</groupId>
  34. <artifactId>springfox-swagger2</artifactId>
  35. <version>2.9.2</version>
  36. </dependency>
  37. <dependency>
  38. <groupId>io.springfox</groupId>
  39. <artifactId>springfox-swagger-ui</artifactId>
  40. <version>2.9.2</version>
  41. </dependency>
  42. <!-- spring boot redis -->
  43. <dependency>
  44. <groupId>org.springframework.boot</groupId>
  45. <artifactId>spring-boot-starter-data-redis</artifactId>
  46. </dependency>
  47. <!-- lettuce pool -->
  48. <dependency>
  49. <groupId>org.apache.commons</groupId>
  50. <artifactId>commons-pool2</artifactId>
  51. </dependency>
  52. </dependencies>
  53.  
  54. <build>
  55. <plugins>
  56. <plugin>
  57. <groupId>org.springframework.boot</groupId>
  58. <artifactId>spring-boot-maven-plugin</artifactId>
  59. </plugin>
  60. </plugins>
  61. </build>
  62.  
  63. </project>

1.添加swagger 配置

添加一个swagger 配置类,在工程下新建 config 包并添加一个 SwaggerConfig 配置类。

SwaggerConfig.java

  1. package com.louis.springboot.demo.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import springfox.documentation.builders.ApiInfoBuilder;
  5. import springfox.documentation.builders.PathSelectors;
  6. import springfox.documentation.builders.RequestHandlerSelectors;
  7. import springfox.documentation.service.ApiInfo;
  8. import springfox.documentation.spi.DocumentationType;
  9. import springfox.documentation.spring.web.plugins.Docket;
  10. import springfox.documentation.swagger2.annotations.EnableSwagger2;
  11. @Configuration
  12. @EnableSwagger2
  13. public class SwaggerConfig {
  14. @Bean
  15. public Docket createRestApi(){
  16. return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
  17. .select()
  18. .apis(RequestHandlerSelectors.any())
  19. .paths(PathSelectors.any()).build();
  20. }
  21. private ApiInfo apiInfo(){
  22. return new ApiInfoBuilder()
  23. .title("Swagger API Doc")
  24. .description("This is a restful api document of Swagger.")
  25. .version("1.0")
  26. .build();
  27. }
  28. }

2.修改application.properties文件名为application.yml,在其中添加Redis配置信息。

application.yml

  1. spring:
  2. redis:
  3. database: 0 # Redis数据库索引(默认为0)
  4. host: localhost # Redis服务器地址
  5. port: 6379 # Redis服务器连接端口
  6. password: # Redis服务器连接密码(默认为空)
  7. lettuce:
  8. pool:
  9. max-active: 8 # 连接池最大连接数(使用负值表示没有限制) 默认 8
  10. max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
  11. max-idle: 8 # 连接池中的最大空闲连接 默认 8
  12. min-idle: 0 # 连接池中的最小空闲连接 默认 0

3.添加一个Redis配置类,使用@EnableCaching注解来开启缓存。

RedisConfig.java

  1. package com.louis.springboot.demo.config;
  2. import java.lang.reflect.Method;
  3. import org.springframework.cache.annotation.CachingConfigurerSupport;
  4. import org.springframework.cache.annotation.EnableCaching;
  5. import org.springframework.cache.interceptor.KeyGenerator;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. @Configuration
  9. @EnableCaching
  10. public class RedisConfig extends CachingConfigurerSupport{
  11. @Bean
  12. public KeyGenerator keyGenerator() {
  13. return new KeyGenerator() {
  14. @Override
  15. public Object generate(Object target, Method method, Object... params) {
  16. StringBuilder sb = new StringBuilder();
  17. sb.append(target.getClass().getName());
  18. sb.append(method.getName());
  19. for (Object obj : params) {
  20. sb.append(obj.toString());
  21. }
  22. return sb.toString();
  23. }
  24. };
  25. }
  26. }

编写一个简单的用户实体类,包含用户名和密码。

User.java

  1. package com.louis.springboot.demo.model;
  2. import java.io.Serializable;
  3. public class User implements Serializable {
  4. private static final long serialVersionUID = 1L;
  5. private String username;
  6. private String password;
  7. public User(String username, String password) {
  8. super();
  9. this.username = username;
  10. this.password = password;
  11. }
  12. public String getUsername() {
  13. return username;
  14. }
  15. public void setUsername(String username) {
  16. this.username = username;
  17. }
  18. public String getPassword() {
  19. return password;
  20. }
  21. public void setPassword(String password) {
  22. this.password = password;
  23. }
  24. @Override
  25. public String toString() {
  26. return "{username:" + getUsername() + ", password:" +getPassword() + "}";
  27. }
  28. }

编写一个业务控制器,分别编写测试字符串和对象的存取接口,另外还通过@Cacheable(value=”user-key”)注解给方法开启缓存,这样就可以缓存方法返回的结果,只有当缓存不存在的时候采用执行方法返回新的用户对象。

RedisController.java

  1. package com.louis.springboot.demo.controller;
  2. import java.util.concurrent.TimeUnit;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.cache.annotation.Cacheable;
  5. import org.springframework.data.redis.core.RedisTemplate;
  6. import org.springframework.data.redis.core.StringRedisTemplate;
  7. import org.springframework.data.redis.core.ValueOperations;
  8. import org.springframework.web.bind.annotation.GetMapping;
  9. import org.springframework.web.bind.annotation.RestController;
  10. import com.louis.springboot.demo.model.User;
  11. @RestController
  12. public class RedisController {
  13. @Autowired
  14. private StringRedisTemplate stringRedisTemplate;
  15. @Autowired
  16. private RedisTemplate redisTemplate;
  17. @GetMapping("/testString")
  18. public String testString() {
  19. stringRedisTemplate.opsForValue().set("name", "louis");
  20. String name = stringRedisTemplate.opsForValue().get("name");
  21. return "the value of key \'name\' is : " + name ;
  22. }
  23. @GetMapping("/testObject")
  24. public String testObject() {
  25. StringBuilder result = new StringBuilder();
  26. User user = new User("louis", "123");
  27. ValueOperations<String, User> operations = redisTemplate.opsForValue();
  28. operations.set("sys.user", user);
  29. operations.set("sys.user.timeout", user, 1, TimeUnit.SECONDS); // 设置1秒后过期
  30. result.append("过期前:").append("\n");
  31. result.append("sys.user=" + operations.get("sys.user")).append("\n");
  32. result.append("sys.user.timeout=" + operations.get("sys.user.timeout"));
  33. try {
  34. Thread.sleep(1000);
  35. } catch (InterruptedException e) {
  36. e.printStackTrace();
  37. }
  38. result.append("\n").append("过期后:").append("\n");
  39. result.append("sys.user=" + operations.get("sys.user")).append("\n");
  40. result.append("sys.user.timeout=" + operations.get("sys.user.timeout"));
  41. return result.toString();
  42. }
  43. @GetMapping("/getUser")
  44. @Cacheable(value="user-key")
  45. public User getUser() {
  46. User user = new User("louis", "123");
  47. System.out.println("用户对象缓存不存在,返回一个新的用户对象。");
  48. return user;
  49. }
  50. }

1.  右键项目 -> Run as -> Maven install,开始执行Maven构建,第一次会下载Maven依赖,可能需要点时间,如果出现如下信息,就说明项目编译打包成功了。

 

2.  右键文件 DemoApplication.java -> Run as -> Java Application,开始启动应用,当出现如下信息的时候,就说明应用启动成功了,默认启动端口是8080。

 

3.  打开浏览器,访问:http://localhost:8080/swagger-ui.html,进入swagger接口文档界面。

4.调用testString接口,如果能出现如下图所示结果就说明成功了

5.调用testObject接口,如果能出现如下图所示结果就说明成功了。

6.调用getUser接口,此时因为是第一次调用此方法,所以没有key值为“user-key”的缓存,所以会执行方法并将返回结果进行缓存。在执行getUser方法的时候控制台输出了我们添加的提示信息如下。

  1. 用户对象缓存不存在,返回一个新的用户对象。

7.然后再次调用getUser接口,发现getUser没有再次被执行,控制台也没有输出上一步的提示信息,那是因为在方法调用之前,应用从key值为“user-key”的缓存中获取成功,所以并不需要继续执行getUser方法的内容了。

 

官方网站:https://redis.io/documentation

百度百科:https://baike.baidu.com/item/Redis/6549233?fr=aladdin

菜鸟教程:https://www.runoob.com/redis/redis-tutorial.html

Spring Boot 系列教程目录导航

Spring Boot:快速入门教程

Spring Boot:整合Swagger文档

Spring Boot:整合MyBatis框架

Spring Boot:实现MyBatis分页

码云:https://gitee.com/liuge1988/spring-boot-demo.git


作者:朝雨忆轻尘
出处:https://www.cnblogs.com/xifengxiaoma/ 
版权所有,欢迎转载,转载请注明原文作者及出处。

版权声明:本文为xifengxiaoma原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/xifengxiaoma/p/11116021.html