栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java > SpringBoot

SpringBoot 中应该怎样使用 Redis ?

SpringBoot 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot 中应该怎样使用 Redis ?

环境信息
  • JDK 版本信息

  1.8

  • SpringBoot 版本、依赖信息

  org.springframework.boot
  spring-boot-starter-parent
  2.0.2.RELEASE
  

我们在 SpringBoot 中使用 Redis 时,会引入如下的 redis starter


  org.springframework.boot
  spring-boot-starter-data-redis

这个 starter 引入了 jedis 和 spring-data-redis 两个与 redis 核心的包。

一些核心类的定义
  • RedisConnection

RedisConnection 处理了与 redis 后端的通信。它提供了底层的方法,可以与redis通信,这些方法的输入和返回都是二进制的值,即 byte[](字节数组)。
如果需要直接使用 RedisConnection,则需要在调用方法时,自己处理序列化和反序列化的问题。

  • RedisTemplate

**与 RedisConnection 相比,RedisTemplate 提供了较为抽象的方法。我们在使用 RedisTemplate 时,通常需要自己去指定 key 和 value 的序列化器。如果没有指定,则
使用默认的 JdkSerializationRedisSerializer(JDK 的序列化策略),可以查看其源码如下: **

public class RedisTemplate extends RedisAccessor implements RedisOperations, BeanClassLoaderAware {

	...

	@SuppressWarnings("rawtypes") private @Nullable RedisSerializer keySerializer = null;
	@SuppressWarnings("rawtypes") private @Nullable RedisSerializer valueSerializer = null;
	@SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashKeySerializer = null;
	@SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashValueSerializer = null;
	private RedisSerializer stringSerializer = new StringRedisSerializer();

  ...

	@Override
	public void afterPropertiesSet() {

		super.afterPropertiesSet();

		boolean defaultUsed = false;

		if (defaultSerializer == null) {

			defaultSerializer = new JdkSerializationRedisSerializer(
					classLoader != null ? classLoader : this.getClass().getClassLoader());
		}

		...

		initialized = true;
}
  • StringRedisTemplate

最常用的 redis 客户端,用于存取 key 和 value 都是字符串类型的数据。默认采用 String 的序列化策略(StringRedisSerializer),可以查看其源码如下:

public class StringRedisTemplate extends RedisTemplate {

	
	public StringRedisTemplate() {
		RedisSerializer stringSerializer = new StringRedisSerializer();
		setKeySerializer(stringSerializer);
		setValueSerializer(stringSerializer);
		setHashKeySerializer(stringSerializer);
		setHashValueSerializer(stringSerializer);
	}

  ...
}
RedisConnection、RedisTemplate 和 StringRedisTemplate 的使用实例
  • Java Object(CityInfo)定义
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;


@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CityInfo implements Serializable {

    
    private String city;

    
    private Double longitude;

    
    private Double latitude;
}
  • Redis 的配置类:RedisConfig
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;


@Configuration
public class RedisConfig {

    private final RedisConnectionFactory redisConnectionFactory;

    @Autowired
    public RedisConfig(RedisConnectionFactory redisConnectionFactory) {
 this.redisConnectionFactory = redisConnectionFactory;
    }

    
    @Bean("RedisConnection")
    RedisConnection getConn(){
 return redisConnectionFactory.getConnection();
    }

    
    @Bean("RedisTemplate")
    RedisTemplate getRedisTemplate(RedisConnectionFactory factory) {

 RedisTemplate template = new RedisTemplate<>();

 // RedisTemplate key/value 默认的序列化策略
 JdkSerializationRedisSerializer redisSerializer = new JdkSerializationRedisSerializer();

 // StringRedisTemplate key/value 默认的序列化策略
 RedisSerializer stringSerializer = new StringRedisSerializer();

 template.setConnectionFactory(factory);
 template.setKeySerializer(stringSerializer);
 template.setValueSerializer(redisSerializer);

 return template;
    }
}
  • 测试用例:RedisOpTest
import com.alibaba.fastjson.JSON;
import com.imooc.ad.Application;
import com.imooc.ad.vo.CityInfo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.test.context.junit4.SpringRunner;

import java.nio.charset.StandardCharsets;


@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class},
 webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class RedisOpTest {

    
    @Autowired
    @Qualifier("RedisConnection")
    private RedisConnection connection;

    
    @Autowired
    @Qualifier("RedisTemplate")
    private RedisTemplate redisTemplate;

    
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Test
    public void testUseRedisConnection() {

 String key = "RedisConnection";

 // -----------------------------------使用 RedisConnection 存取 String 对象---------------------------------------

 String value = "qinyi";

 connection.set(key.getBytes(StandardCharsets.UTF_8), value.getBytes(StandardCharsets.UTF_8));

 byte[] ret = connection.get(key.getBytes(StandardCharsets.UTF_8));
 assert ret != null;
 System.out.println(new String(ret));

 connection.flushAll();  // 慎用

 // -----------------------------------使用 RedisConnection 存取 Java 对象-----------------------------------------

 CityInfo cityInfo = CityInfo.builder()
  .city("suzhou").longitude(116.58).latitude(33.38).build();

 JdkSerializationRedisSerializer serializer = new JdkSerializationRedisSerializer();
 connection.set(key.getBytes(StandardCharsets.UTF_8), serializer.serialize(cityInfo));

 System.out.println(serializer.deserialize(connection.get(key.getBytes(StandardCharsets.UTF_8))));

 connection.flushAll();  // 慎用
    }

    @Test
    public void testUseRedisTemplate() {

 String key = "RedisTemplate";

 // -----------------------------------使用 RedisTemplate 存取 Java 对象-------------------------------------------

 CityInfo cityInfo = CityInfo.builder()
  .city("suzhou").longitude(116.58).latitude(33.38).build();

 ValueOperations valueOperations = redisTemplate.opsForValue();
 valueOperations.set(key, cityInfo);

 System.out.println(valueOperations.get(key));

 connection.flushAll();  // 慎用
    }

    @Test
    public void testUseStringRedisTemplate() {

 String key = "StringRedisTemplate";

 // -----------------------------------使用 StringRedisTemplate 存取 String 对象-----------------------------------

 CityInfo cityInfo = CityInfo.builder()
  .city("suzhou").longitude(116.58).latitude(33.38).build();

 ValueOperations valueOperations = stringRedisTemplate.opsForValue();
 valueOperations.set(key, JSON.toJSONString(cityInfo));

 System.out.println(JSON.parseObject(valueOperations.get(key), CityInfo.class));

 connection.flushAll();  // 慎用
    }
}
总结
  • 当需要存取的数据是字符串类型时(大多数情况下),使用 StringRedisTemplate
  • 当需要存取的数据是 Java Object 时,使用 RedisTemplate(需要定义好序列化策略)
  • 不需要使用 RedisConnection

欢迎关注课程:

基于 SpringCloud 微服务架构下 广告系统设计与实现

JAVA分布式优惠券系统后台 手把手实战开发

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号