springboot2.x整合redis实现缓存(附github链接)
本文代码已提交github: https://github.com/LCABC777/Springboot-redis(1)Springboot中使用redis操作的两种方式:lettuce和jedis,两者在进行操作时都需要序列化器来实现序列化
(推荐使用jackson2JsonRedisSerializer,相比于JDK提供的序列化器和String序列化器长度更短),
lettuce和redis都是 redis的客户端。
(2)Springboot 1.x整合Spring-data-redis底层用的是jedis,Springboot 2.x整合spring-data-redis用的是lettuce,
jedis在多线程环境下是非线程安全的,使用了jedis pool连接池,为每个Jedis实例增加物理连接。
Lettuce的连接是基于Netty的,连接实例(StatefulRedisConnection)可以在多个线程间并发访问。
本文的基本环境:
springboot: 2.x
redis版本:redis 3.0.0
linux系统:centos 6.5
jdk:1.8
(1)添加maven依赖
<!--web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--redis依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId></dependency>
<!--junit依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--spring test测试依赖>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
(2)application.properties中redis数据源及lettuce客户端配置
#redis
# 连接设置
spring.redis.database=0
spring.redis.host=192.168.18.128
spring.redis.port=6379
spring.redis.password=123456
spring.redis.timeout=10000ms
# 连接池设置
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.max-wait=
spring.redis.lettuce.pool.min-idle=0
spring.redis.lettuce.pool.max-active=8
(3)redis模板(redisTemplate,提供对redis数据库的操作方法)及缓存管理器(cacheManager)配置
package com.lc.config; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.*;
import javax.annotation.Resource;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map; @Configuration
public class RedisConfig {
//lettuce客户端连接工厂
@Resource
private LettuceConnectionFactory lettuceConnectionFactory;
//日志
private Logger logger=LoggerFactory.getLogger(RedisConfig.class);
//json序列化器
private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//缓存生存时间
private Duration timeToLive = Duration.ofDays(1);
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
//redis缓存配置
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(this.timeToLive)
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()))
.disableCachingNullValues();
//缓存配置map
Map<String,RedisCacheConfiguration> cacheConfigurationMap=new HashMap<>();
//自定义缓存名,后面使用的@Cacheable的CacheName
cacheConfigurationMap.put("users",config);
cacheConfigurationMap.put("default",config);
//根据redis缓存配置和reid连接工厂生成redis缓存管理器
RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory)
.cacheDefaults(config)
.transactionAware()
.withInitialCacheConfigurations(cacheConfigurationMap)
.build();
logger.debug("自定义RedisCacheManager加载完成");
return redisCacheManager;
} //redisTemplate模板提供给其他类对redis数据库进行操作
@Bean(name = "redisTemplate")
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(keySerializer());
redisTemplate.setHashKeySerializer(keySerializer());
redisTemplate.setValueSerializer(valueSerializer());
redisTemplate.setHashValueSerializer(valueSerializer());
logger.debug("自定义RedisTemplate加载完成");
return redisTemplate;
}
//redis键序列化使用StrngRedisSerializer
private RedisSerializer<String> keySerializer() {
return new StringRedisSerializer();
}
//redis值序列化使用json序列化器
private RedisSerializer<Object> valueSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
//缓存键自动生成器
@Bean
public KeyGenerator myKeyGenerator() {
return (target, method, params) -> {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
};
}
}
(4)利用redisTemplate进行对redis数据库的操作
注入redisTemplate
@Autowired
private RedisTemplate redisTemplate;
(5)使用redis的hash来存储map,并做缓存处理,用来验证是否成功
//添加hash,需要hash名和存储的键值对Map
public void setHash(String hashName,Map<String,String> map) {
redisTemplate.opsForHash().putAll(hashName,map);
}
//Springboot的启动器main方法上需要加上@EnableCaching开启缓存,使用了@Cacheable注解后,缓存的值将被存入redis数据库中
//缓存名可以为RedisConfig中自定义的缓存名,键生成器为RedisConig中自定义的键生成器,也可以自己自定义缓存key名
@Cacheable(cacheNames = "users",keyGenerator ="myKeyGenerator")
//从redis中获取map
public Map<Object,Object> getHash(String hashName){
if (redisTemplate.hasKey(hashName)) {
System.out.println(redisTemplate.opsForHash().entries(hashName));
return redisTemplate.opsForHash().entries(hashName);
}else {
return null;
}
}
(6)使用junit来测试缓存
import com.lc.Starter;
import com.lc.service.RedisService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.HashMap;
import java.util.Map; @RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Starter.class)
public class MyTest {
@Autowired
private RedisService redisService; @Test
public void hashTest(){
Map<String,String> map=new HashMap<>();
map.put("a879","1");
map.put("2131","23");
//redis中添加hash
redisService.setHash("ccc",map);
//多次获取hash
Map hash=redisService.getHash("ccc");
redisService.getHash("ccc");
redisService.getHash("ccc")
if (hash!=null){
System.out.println(hash.toString());
}
}
}
(7)多次获取hash,测试结果只执行了两次打印方法,说明除了第一次都是从redis的缓存库中读取的缓存,而不是getHash中的redisTemplate.opsForHash().entries(hashName)
(8)从redisDesktop中可以清楚的看到redis的存储,setHash方法将ccc这个hash存入了redis库中,而getHash方法做缓存处理后,程序直接将包名+方法名+参数这个由keyGenertor自动生成的字符串作为key, Geneic json序列化器将要缓存类型在java中的包名和缓存的值组成json串作为value实现了缓存
本文代码已提交github: https://github.com/LCABC777/Springboot-redis
springboot2.x整合redis实现缓存(附github链接)的更多相关文章
- springboot2.0整合redis作为缓存以json格式存储对象
步骤1 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spr ...
- SpringBoot2.x整合Redis实战 4节课
1.分布式缓存Redis介绍 简介:讲解为什么要用缓存和介绍什么是Redis,新手练习工具 1.redis官网 https://redis.io/download 2.新手 ...
- 小D课堂 - 零基础入门SpringBoot2.X到实战_第9节 SpringBoot2.x整合Redis实战_39、SpringBoot2.x整合redis实战讲解
笔记 3.SpringBoot2.x整合redis实战讲解 简介:使用springboot-starter整合reids实战 1.官网:https://docs.spring.io/spring-bo ...
- SpringBoot2.x整合Prometheus+Grafana【附源码+视频】
图文并茂,新手入门教程,建议收藏 SpringBoot2.x整合Prometheus+Grafana[附源码+视频] 附源码+视频 目录 工程简介 简介 Prometheus grafana Spri ...
- Spring Boot 整合 Redis 实现缓存操作
摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 产品没有价值,开发团队再优秀也无济于事 – <启示录> 』 本文提纲 ...
- SpringBoot2.0 整合 Redis集群 ,实现消息队列场景
本文源码:GitHub·点这里 || GitEE·点这里 一.Redis集群简介 1.RedisCluster概念 Redis的分布式解决方案,在3.0版本后推出的方案,有效地解决了Redis分布式的 ...
- 从零搭建Spring Boot脚手架(6):整合Redis作为缓存
1. 前言 上一文我们整合了Mybatis Plus,今天我们会把缓存也集成进来.缓存是一个系统应用必备的一种功能,除了在减轻数据库的压力之外.还在存储一些短时效的数据场景中发挥着重大作用,比如存储用 ...
- Spring Boot 整合Redis 实现缓存
本文提纲 一.缓存的应用场景 二.更新缓存的策略 三.运行 springboot-mybatis-redis 工程案例 四.springboot-mybatis-redis 工程代码配置详解 ...
- Springboot2.0整合Redis(注解开发)
一. pom.xm文件引入对应jar包 <dependency> <groupId>org.springframework.boot</groupId> <a ...
随机推荐
- 如何在 CentOS 7 上安装 Python 3
当前最新的 CentOS 7.5 默认安装的是 Python 2.7.5,并且默认的官方 yum 源中不提供 Python 3 的安装包.这里主要介绍两种在 CentOS 7 中安装 Python 3 ...
- 跟踪路由 tracert
由于最近遇到网络出现故障的问题,便使用到Tracert来确定了下出现故障的网络节点 记录下tracert命令相关内容 1. 简介 2. Tracert工作原理... 3. 常用参数 4. 使用示例与输 ...
- Python9-网络编程3-day32
解决黏包的问题 #server import socket sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen() conn,addr ...
- LeetCode(117) Populating Next Right Pointers in Each Node II
题目 Follow up for problem "Populating Next Right Pointers in Each Node". What if the given ...
- hdu-1231 连续最大子序列(动态规划)
Time limit1000 ms Memory limit32768 kB 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj ...
- cf 1016C
C. Vasya And The Mushrooms time limit per test 2 seconds memory limit per test 256 megabytes input s ...
- loj2001 「SDOI2017」树点涂色
there #include <iostream> #include <cstdio> using namespace std; int n, m, dfn[100005], ...
- luogu1441 砝码称重
搜索+背包就是了 #include <iostream> #include <cstring> #include <cstdio> using namespace ...
- [Oracle] Lob介绍
[Oracle] Lob介绍 像Oracle这种关系型数据库,比较擅长处理结构化的数据,那么对于非结构化的数据,Oracle是怎么处理和存储的呢?Lob (Large Object)是Oracle ...
- 微信小程序开发 -- 手机振动
wx.vibrateLong(OBJECT) wx.vibrateLong(OBJECT) 方法使手机发生较长时间的振动(400ms) OBJECT参数说明: 参数名 类型 必填 说明 success ...