您的位置:首页 > 数据库 > Redis

springboot2.x整合redis实现缓存(附github链接)

2019-05-19 16:57 1541 查看

本文代码已提交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

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: