Spring Data Redis 设计分析

Spring Data Redis 介绍

Spring Data Redis 是属于 Spring Data 下的一个模块,作用就是简化对于 redis 的操做。

1、提供了一个高度封装的“RedisTemplate”类,里面封装了对于Redis的五种数据结构的各种操作,包括:

  • redisTemplate.opsForValue():操作字符串
  • redisTemplate.opsForHash():操作hash
  • redisTemplate.opsForList():操作list
  • redisTemplate.opsForSet():操作set
  • redisTemplate.opsForZSet():操作zset
    2、SpringBoot2.x后RedisTemplate采用是lettuce(基于netty采用异步非阻塞式lO)进行通信,大并发下比jedis效率更高。
    3、RedisTemplate模板使用序列化器操作redis数据。

RedisTemplate

操作

Redis 的类型包括 Value、List、Set、Stream、ZSet、Geo、HyperLogLog 、Cluster 操作。它们之间的关系如下:
spring data redis

序列化

public interface RedisSerializer<T> {
    @Nullable
    byte[] serialize(@Nullable T var1) throws SerializationException;

    @Nullable
    T deserialize(@Nullable byte[] var1) throws SerializationException;
}

spring data redis serializer

类型转换

在 RedisCustomConversions 和 Jsr310Converters 定义了常见的类型转换。

RedisCustomConversions 中定义的转换器:

public class RedisCustomConversions extends CustomConversions {
    static {
        List<Object> converters = new ArrayList();
        converters.add(new StringToBytesConverter());
        converters.add(new BytesToStringConverter());
        converters.add(new NumberToBytesConverter());
        converters.add(new BytesToNumberConverterFactory());
        converters.add(new EnumToBytesConverter());
        converters.add(new BytesToEnumConverterFactory());
        converters.add(new BooleanToBytesConverter());
        converters.add(new BytesToBooleanConverter());
        converters.add(new DateToBytesConverter());
        converters.add(new BytesToDateConverter());
        converters.add(new UuidToBytesConverter());
        converters.add(new BytesToUuidConverter());
        converters.addAll(Jsr310Converters.getConvertersToRegister());
        STORE_CONVERTERS = Collections.unmodifiableList(converters);
        STORE_CONVERSIONS = StoreConversions.of(SimpleTypeHolder.DEFAULT, STORE_CONVERTERS);
    }
}

Jsr310Converters 中定义的转换器:

public abstract class Jsr310Converters {
    public static Collection<Converter<?, ?>> getConvertersToRegister() {
        if (!JAVA_8_IS_PRESENT) {
            return Collections.emptySet();
        } else {
            List<Converter<?, ?>> converters = new ArrayList();
            converters.add(new Jsr310Converters.LocalDateTimeToBytesConverter());
            converters.add(new Jsr310Converters.BytesToLocalDateTimeConverter());
            converters.add(new Jsr310Converters.LocalDateToBytesConverter());
            converters.add(new Jsr310Converters.BytesToLocalDateConverter());
            converters.add(new Jsr310Converters.LocalTimeToBytesConverter());
            converters.add(new Jsr310Converters.BytesToLocalTimeConverter());
            converters.add(new Jsr310Converters.ZonedDateTimeToBytesConverter());
            converters.add(new Jsr310Converters.BytesToZonedDateTimeConverter());
            converters.add(new Jsr310Converters.InstantToBytesConverter());
            converters.add(new Jsr310Converters.BytesToInstantConverter());
            converters.add(new Jsr310Converters.ZoneIdToBytesConverter());
            converters.add(new Jsr310Converters.BytesToZoneIdConverter());
            converters.add(new Jsr310Converters.PeriodToBytesConverter());
            converters.add(new Jsr310Converters.BytesToPeriodConverter());
            converters.add(new Jsr310Converters.DurationToBytesConverter());
            converters.add(new Jsr310Converters.BytesToDurationConverter());
            return converters;
        }
    }
}

spring data redis convert

监听器

功能列表

1、支持 Pattern Topic 和 KeyspaceEvent 支持
2、通过 MessageListener 监听Redis Pub/Sub消息
3、监听 KeyspaceEvent 事件 __keyevent@*
4、监听KeyExpirationEvent 事件 __keyevent@*__:expire

@FunctionalInterface
public interface MessageListener {
	void onMessage(Message message, byte[] pattern);
}

主流程如下

    public void onMessage(Message message, @Nullable byte[] pattern) {
        try {
            if (this.delegate != this && this.delegate instanceof MessageListener) {
                // 如果是 MessageListener,直接执行并返回
                ((MessageListener)this.delegate).onMessage(message, pattern);
                return;
            }
            Object convertedMessage = this.extractMessage(message);
            // 获取反射方法参数
            String convertedChannel = (String)this.stringSerializer.deserialize(pattern);
            Object[] listenerArguments = new Object[]{convertedMessage, convertedChannel};
            // 反射调用
            this.invokeListenerMethod(this.invoker.getMethodName(), listenerArguments);
        } catch (Throwable var6) {
            this.handleListenerException(var6);
        }

    }

监听到消息之后,通过反射执行方法。

执行 Lua 脚本

Redis 支持执行 lua 脚本,包括两部分
1、脚本内容
2、脚本执行

脚本内容
public interface RedisScript<T> {
	String getSha1();

	Class<T> getResultType();

	String getScriptAsString();

包括脚本内容和返回类型。默认实现类为DefaultRedisScript。

对于脚本内容核心在于内容的来源,通过 ScriptSource 进行抽象,当前默认实现包括 ResourceScriptSource (从 Resource 读取)和 StaticScriptSource(直接为字符串)。

脚本的执行
public interface ScriptExecutor<K> {
	<T> T execute(RedisScript<T> script, List<K> keys, Object... args);

	<T> T execute(RedisScript<T> script, RedisSerializer<?> argsSerializer, RedisSerializer<T> resultSerializer,
			List<K> keys, Object... args);
}

默认实现为 DefaultScriptExecutor,包括如下几部分
1、参数序列化:抽象为 RedisSerializer
2、执行脚本:依赖 RedisTemplate 进行的 eval 和 evalSha 命令。
3、结果序列化:抽象为 RedisSerializer
4、返回值类:通过 ReturnType 转换

连接

支持 Lettuce 和 Jedis 两种客户端。其中 Lettuce 支持 Reactive RedisTemplae

操作

SessionCallback
public interface SessionCallback<T> {
    @Nullable
    <K, V> T execute(RedisOperations<K, V> var1) throws DataAccessException;
}
RedisCallback

public interface RedisCallback<T> {
    @Nullable
    T doInRedis(RedisConnection var1) throws DataAccessException;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值