Redisson2.0源码分析2-Redis命令封装
Redisson2.0源码分析2-Redis命令封装
命令封装这块的代码并不是特别多。
1. Redis命令细节封装 RedisCommand
这个类封装一个 Redis 命令的所有必要信息,有 Redis 命令名称、Redis命令的参数类型、命令请求以及应答解码器和转换器等。
这个适用于 Redisson 用来描述以及处理 Redis 命令的。对于 Redisson 来说,发送命令编解码以及命令应答处理都应该是一个固定的流程,那么这个流程需要的参数定义就可以写在这个类中。
package org.redisson.client.protocol;
import java.util.Arrays;
import java.util.List;
import org.redisson.client.protocol.convertor.Convertor;
import org.redisson.client.protocol.convertor.EmptyConvertor;
import org.redisson.client.protocol.decoder.MultiDecoder;
public class RedisCommand<R> {
// Redis 命令参数以及返回值的类型枚举
public enum ValueType {OBJECT, OBJECTS, MAP_VALUE, MAP_KEY, MAP}
private ValueType outParamType = ValueType.OBJECT; // 输出参数的类型,默认为 OBJECT
private List<ValueType> inParamType = Arrays.asList(ValueType.OBJECT); // 输入参数的类型,默认为 OBJECT
private final int inParamIndex; // 输入参数的下标
private final String name; // 命令的名称
private final String subName; // 子命令名称
// 多条 Redis 响应解码器,比如像 Multi 命令这种返回的结果
private MultiDecoder<R> replayMultiDecoder;
// 单条 Redis 回复的解码器
private Decoder<R> replayDecoder;
// 值转换器。比如 Redis 返回 01 ,程序中转成 true false
Convertor<R> convertor = new EmptyConvertor<R>();
public RedisCommand(RedisCommand<R> command, String name) {
this.outParamType = command.outParamType;
this.inParamType = command.inParamType;
this.inParamIndex = command.inParamIndex;
this.name = name;
this.subName = command.subName;
this.replayMultiDecoder = command.replayMultiDecoder;
this.replayDecoder = command.replayDecoder;
this.convertor = command.convertor;
}
// 下面一堆重载函数都是为了创建不同的命令对象。
public RedisCommand(String name) {
this(name, (String)null);
}
public RedisCommand(String name, ValueType outParamType) {
this(name, (String)null);
this.outParamType = outParamType;
}
public RedisCommand(String name, int objectParamIndex, ValueType inParamType) {
this(name, null, null, null, objectParamIndex);
this.inParamType = Arrays.asList(inParamType);
}
public RedisCommand(String name, ValueType inParamType, ValueType outParamType) {
this(name, (String)null);
this.inParamType = Arrays.asList(inParamType);
this.outParamType = outParamType;
}
public RedisCommand(String name, String subName) {
this(name, subName, null, null, -1);
}
public RedisCommand(String name, String subName, Convertor<R> convertor) {
this(name, subName, null, null, -1);
this.convertor = convertor;
}
public RedisCommand(String name, String subName, int objectParamIndex) {
this(name, subName, null, null, objectParamIndex);
}
public RedisCommand(String name, int encodeParamIndex) {
this(name, null, null, null, encodeParamIndex);
}
public RedisCommand(String name, int encodeParamIndex, ValueType inParamType, ValueType outParamType) {
this(name, null, null, null, encodeParamIndex);
this.inParamType = Arrays.asList(inParamType);
this.outParamType = outParamType;
}
public RedisCommand(String name, int encodeParamIndex, List<ValueType> inParamType, ValueType outParamType) {
this(name, null, null, null, encodeParamIndex);
this.inParamType = inParamType;
this.outParamType = outParamType;
}
public RedisCommand(String name, Decoder<R> reponseDecoder, int encodeParamIndex, List<ValueType> inParamType, ValueType outParamType) {
this(name, null, null, reponseDecoder, encodeParamIndex);
this.inParamType = inParamType;
this.outParamType = outParamType;
}
public RedisCommand(String name, Decoder<R> reponseDecoder, int encodeParamIndex, List<ValueType> inParamType) {
this(name, null, null, reponseDecoder, encodeParamIndex);
this.inParamType = inParamType;
}
public RedisCommand(String name, Convertor<R> convertor, int encodeParamIndex, ValueType inParamType) {
this(name, null, null, null, encodeParamIndex);
this.convertor = convertor;
this.inParamType = Arrays.asList(inParamType);
}
public RedisCommand(String name, Convertor<R> convertor, int encodeParamIndex, List<ValueType> inParamTypes) {
this(name, null, null, null, encodeParamIndex);
this.convertor = convertor;
this.inParamType = inParamTypes;
}
public RedisCommand(String name, Convertor<R> convertor) {
this(name, convertor, -1);
}
public RedisCommand(String name, Convertor<R> convertor, int encodeParamIndex) {
this(name, null, null, null, encodeParamIndex);
this.convertor = convertor;
}
public RedisCommand(String name, Decoder<R> reponseDecoder) {
this(name, null, null, reponseDecoder, -1);
}
public RedisCommand(String name, Decoder<R> reponseDecoder, int objectParamIndex, ValueType inParamType) {
this(name, null, null, reponseDecoder, objectParamIndex);
this.inParamType = Arrays.asList(inParamType);
}
public RedisCommand(String name, Decoder<R> reponseDecoder, int objectParamIndex) {
this(name, null, null, reponseDecoder, objectParamIndex);
}
public RedisCommand(String name, MultiDecoder<R> replayMultiDecoder, ValueType outParamType) {
this(name, replayMultiDecoder, -1);
this.outParamType = outParamType;
}
public RedisCommand(String name, MultiDecoder<R> replayMultiDecoder, int objectParamIndex, ValueType inParamType, ValueType outParamType) {
this(name, replayMultiDecoder, objectParamIndex);
this.outParamType = outParamType;
this.inParamType = Arrays.asList(inParamType);
}
public RedisCommand(String name, MultiDecoder<R> replayMultiDecoder) {
this(name, replayMultiDecoder, -1);
}
public RedisCommand(String name, MultiDecoder<R> replayMultiDecoder, Convertor<R> convertor) {
this(name, replayMultiDecoder, -1);
this.convertor = convertor;
}
public RedisCommand(String name, MultiDecoder<R> replayMultiDecoder, int objectParamIndex) {
this(name, null, replayMultiDecoder, null, objectParamIndex);
}
public RedisCommand(String name, String subName, MultiDecoder<R> replayMultiDecoder,
int objectParamIndex) {
this(name, subName, replayMultiDecoder, null, objectParamIndex);
}
public RedisCommand(String name, String subName, MultiDecoder<R> replayMultiDecoder, Decoder<R> reponseDecoder, int objectParamIndex) {
super();
this.name = name;
this.subName = subName;
this.replayMultiDecoder = replayMultiDecoder;
this.replayDecoder = reponseDecoder;
this.inParamIndex = objectParamIndex;
}
public String getSubName() {
return subName;
}
public String getName() {
return name;
}
public Decoder<R> getReplayDecoder() {
return replayDecoder;
}
public int getInParamIndex() {
return inParamIndex;
}
public MultiDecoder<R> getReplayMultiDecoder() {
return replayMultiDecoder;
}
public Convertor<R> getConvertor() {
return convertor;
}
public List<ValueType> getInParamType() {
return inParamType;
}
public ValueType getOutParamType() {
return outParamType;
}
@Override
public String toString() {
return "RedisCommand [name=" + name + ", subName=" + subName + "]";
}
}
2. 严格命令细节封装 RedisStrictCommand
这个类是 RedisCommand 的子类。 上面看 RedisCommand 的代码可以看出, RedisCommand 提供了太多的构造函数。而 RedisStrictCommand 则提供几个很明确的构造函数,这几个构造函数明确参数名称、类型、解码器以及转换器等。
相比于父类,这些构造函数更加清晰明了。
package org.redisson.client.protocol;
import org.redisson.client.protocol.convertor.Convertor;
import org.redisson.client.protocol.decoder.MultiDecoder;
public class RedisStrictCommand<T> extends RedisCommand<T> {
public RedisStrictCommand(String name, int objectParamIndex, ValueType inParamType) {
super(name, (Decoder<T>)null, objectParamIndex, inParamType);
}
public RedisStrictCommand(String name, MultiDecoder<T> replayMultiDecoder) {
super(name, replayMultiDecoder);
}
public RedisStrictCommand(String name, String subName, MultiDecoder<T> replayMultiDecoder) {
super(name, subName, replayMultiDecoder, -1);
}
public RedisStrictCommand(String name) {
super(name);
}
public RedisStrictCommand(String name, Convertor<T> convertor) {
super(name, convertor, -1);
}
public RedisStrictCommand(String name, String subName, Convertor<T> convertor) {
super(name, subName, convertor);
}
public RedisStrictCommand(String name, String subName, MultiDecoder<T> replayMultiDecoder, Convertor convertor) {
super(name, subName, replayMultiDecoder, -1);
this.convertor = convertor;
}
public RedisStrictCommand(String name, String subName, Decoder<T> reponseDecoder) {
super(name, subName, null, reponseDecoder, -1);
}
public RedisStrictCommand(String name, Decoder<T> reponseDecoder) {
super(name, reponseDecoder);
}
}
3. Redis命令集合 RedisCommands
这个接口中声明了所有的 Redis 命令集合。 定义了命令的名称、参数数量、返回类型、返回类型解码器等。可以说是一个很核心的配置类,针对 Redis 返回的数据解码时需要从这里获取对应的解码器信息。
这个里面可以找到目前 Redisson 用到以及暂时没有用到的所有命令集合。
package org.redisson.client.protocol;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.redisson.client.protocol.RedisCommand.ValueType;
import org.redisson.client.protocol.convertor.BooleanAmountReplayConvertor;
import org.redisson.client.protocol.convertor.BooleanReplayConvertor;
import org.redisson.client.protocol.convertor.IntegerReplayConvertor;
import org.redisson.client.protocol.convertor.KeyValueConvertor;
import org.redisson.client.protocol.convertor.TrueReplayConvertor;
import org.redisson.client.protocol.convertor.VoidReplayConvertor;
import org.redisson.client.protocol.decoder.KeyValueObjectDecoder;
import org.redisson.client.protocol.decoder.ListScanResult;
import org.redisson.client.protocol.decoder.ListScanResultReplayDecoder;
import org.redisson.client.protocol.decoder.MapScanResult;
import org.redisson.client.protocol.decoder.MapScanResultReplayDecoder;
import org.redisson.client.protocol.decoder.NestedMultiDecoder;
import org.redisson.client.protocol.decoder.ObjectListReplayDecoder;
import org.redisson.client.protocol.decoder.ObjectMapReplayDecoder;
import org.redisson.client.protocol.decoder.ObjectSetReplayDecoder;
import org.redisson.client.protocol.decoder.StringDataDecoder;
import org.redisson.client.protocol.decoder.StringListReplayDecoder;
import org.redisson.client.protocol.decoder.StringMapDataDecoder;
import org.redisson.client.protocol.decoder.StringMapReplayDecoder;
import org.redisson.client.protocol.decoder.StringReplayDecoder;
import org.redisson.client.protocol.pubsub.PubSubStatusDecoder;
public interface RedisCommands {
// 下面的命令都是 Redis 命令,以及对应的返回值解码器、转换器等。 查询 Redis 文档即可。
RedisCommand<ListScanResult<String>> SCAN = new RedisCommand<ListScanResult<String>>("SCAN", new NestedMultiDecoder(new ObjectListReplayDecoder<String>(), new ListScanResultReplayDecoder()), ValueType.OBJECT);
RedisStrictCommand<String> RANDOM_KEY = new RedisStrictCommand<String>("RANDOMKEY", new StringDataDecoder());
RedisStrictCommand<String> PING = new RedisStrictCommand<String>("PING");
RedisStrictCommand<Void> UNWATCH = new RedisStrictCommand<Void>("UNWATCH", new VoidReplayConvertor());
RedisStrictCommand<Void> WATCH = new RedisStrictCommand<Void>("WATCH", new VoidReplayConvertor());
RedisStrictCommand<Void> MULTI = new RedisStrictCommand<Void>("MULTI", new VoidReplayConvertor());
RedisCommand<List<Object>> EXEC = new RedisCommand<List<Object>>("EXEC", new ObjectListReplayDecoder<Object>());
RedisCommand<Long> SREM = new RedisCommand<Long>("SREM", 2, ValueType.OBJECTS);
RedisCommand<Boolean> SADD = new RedisCommand<Boolean>("SADD", new BooleanAmountReplayConvertor(), 2, ValueType.OBJECTS);
RedisCommand<Object> SPOP_SINGLE = new RedisCommand<Object>("SPOP");
RedisCommand<Boolean> SADD_SINGLE = new RedisCommand<Boolean>("SADD", new BooleanReplayConvertor(), 2);
RedisCommand<Boolean> SREM_SINGLE = new RedisCommand<Boolean>("SREM", new BooleanReplayConvertor(), 2);
RedisCommand<List<Object>> SMEMBERS = new RedisCommand<List<Object>>("SMEMBERS", new ObjectListReplayDecoder<Object>());
RedisCommand<ListScanResult<Object>> SSCAN = new RedisCommand<ListScanResult<Object>>("SSCAN", new NestedMultiDecoder(new ObjectListReplayDecoder<Object>(), new ListScanResultReplayDecoder()), ValueType.OBJECT);
RedisCommand<Boolean> SISMEMBER = new RedisCommand<Boolean>("SISMEMBER", new BooleanReplayConvertor(), 2);
RedisStrictCommand<Integer> SCARD = new RedisStrictCommand<Integer>("SCARD", new IntegerReplayConvertor());
RedisCommand<Void> LSET = new RedisCommand<Void>("LSET", new VoidReplayConvertor(), 3);
RedisCommand<Object> LPOP = new RedisCommand<Object>("LPOP");
RedisCommand<Boolean> LREM_SINGLE = new RedisCommand<Boolean>("LREM", new BooleanReplayConvertor(), 3);
RedisCommand<Long> LREM = new RedisCommand<Long>("LREM", 3);
RedisCommand<Object> LINDEX = new RedisCommand<Object>("LINDEX");
RedisCommand<Object> LINSERT = new RedisCommand<Object>("LINSERT", 3, ValueType.OBJECTS);
RedisStrictCommand<Integer> LLEN = new RedisStrictCommand<Integer>("LLEN", new IntegerReplayConvertor());
RedisStrictCommand<Boolean> LTRIM = new RedisStrictCommand<Boolean>("LTRIM", new BooleanReplayConvertor());
RedisStrictCommand<Boolean> EXPIRE = new RedisStrictCommand<Boolean>("EXPIRE", new BooleanReplayConvertor());
RedisStrictCommand<Boolean> EXPIREAT = new RedisStrictCommand<Boolean>("EXPIREAT", new BooleanReplayConvertor());
RedisStrictCommand<Boolean> PERSIST = new RedisStrictCommand<Boolean>("PERSIST", new BooleanReplayConvertor());
RedisStrictCommand<Long> TTL = new RedisStrictCommand<Long>("TTL");
RedisCommand<Object> RPOPLPUSH = new RedisCommand<Object>("RPOPLPUSH");
RedisCommand<Object> BRPOPLPUSH = new RedisCommand<Object>("BRPOPLPUSH");
RedisCommand<Object> BLPOP = new RedisCommand<Object>("BLPOP", new KeyValueObjectDecoder());
RedisCommand<Object> BLPOP_VALUE = new RedisCommand<Object>("BLPOP", new KeyValueObjectDecoder(), new KeyValueConvertor());
RedisCommand<Boolean> PFADD = new RedisCommand<Boolean>("PFADD", new BooleanReplayConvertor(), 2);
RedisCommand<Long> PFCOUNT = new RedisCommand<Long>("PFCOUNT");
RedisStrictCommand<Void> PFMERGE = new RedisStrictCommand<Void>("PFMERGE", new VoidReplayConvertor());
RedisCommand<Long> RPOP = new RedisCommand<Long>("RPOP");
RedisCommand<Long> LPUSH = new RedisCommand<Long>("LPUSH");
RedisCommand<List<Object>> LRANGE = new RedisCommand<List<Object>>("LRANGE", new ObjectListReplayDecoder<Object>());
RedisCommand<Long> RPUSH = new RedisCommand<Long>("RPUSH", 2, ValueType.OBJECTS);
RedisCommand<Boolean> RPUSH_BOOLEAN = new RedisCommand<Boolean>("RPUSH", new TrueReplayConvertor(), 2, ValueType.OBJECTS);
RedisStrictCommand<String> SCRIPT_LOAD = new RedisStrictCommand<String>("SCRIPT", "LOAD", new StringDataDecoder());
RedisStrictCommand<Boolean> SCRIPT_KILL = new RedisStrictCommand<Boolean>("SCRIPT", "KILL", new BooleanReplayConvertor());
RedisStrictCommand<Boolean> SCRIPT_FLUSH = new RedisStrictCommand<Boolean>("SCRIPT", "FLUSH", new BooleanReplayConvertor());
RedisStrictCommand<List<Boolean>> SCRIPT_EXISTS = new RedisStrictCommand<List<Boolean>>("SCRIPT", "EXISTS", new ObjectListReplayDecoder<Boolean>(), new BooleanReplayConvertor());
RedisStrictCommand<Boolean> EVAL_BOOLEAN = new RedisStrictCommand<Boolean>("EVAL", new BooleanReplayConvertor());
RedisStrictCommand<String> EVAL_STRING = new RedisStrictCommand<String>("EVAL", new StringReplayDecoder());
RedisStrictCommand<Long> EVAL_INTEGER = new RedisStrictCommand<Long>("EVAL");
RedisCommand<List<Object>> EVAL_LIST = new RedisCommand<List<Object>>("EVAL", new ObjectListReplayDecoder<Object>());
RedisCommand<Object> EVAL_OBJECT = new RedisCommand<Object>("EVAL");
RedisCommand<Object> EVAL_MAP_VALUE = new RedisCommand<Object>("EVAL", ValueType.MAP_VALUE);
RedisCommand<List<Object>> EVAL_MAP_VALUE_LIST = new RedisCommand<List<Object>>("EVAL", new ObjectListReplayDecoder<Object>(), ValueType.MAP_VALUE);
RedisStrictCommand<Long> INCR = new RedisStrictCommand<Long>("INCR");
RedisStrictCommand<Long> INCRBY = new RedisStrictCommand<Long>("INCRBY");
RedisStrictCommand<Long> DECR = new RedisStrictCommand<Long>("DECR");
RedisStrictCommand<String> AUTH = new RedisStrictCommand<String>("AUTH", new StringReplayDecoder());
RedisStrictCommand<String> SELECT = new RedisStrictCommand<String>("SELECT", new StringReplayDecoder());
RedisStrictCommand<Boolean> CLIENT_SETNAME = new RedisStrictCommand<Boolean>("CLIENT", "SETNAME", new BooleanReplayConvertor());
RedisStrictCommand<String> CLIENT_GETNAME = new RedisStrictCommand<String>("CLIENT", "GETNAME", new StringDataDecoder());
RedisStrictCommand<Void> FLUSHDB = new RedisStrictCommand<Void>("FLUSHDB", new VoidReplayConvertor());
RedisStrictCommand<Void> FLUSHALL = new RedisStrictCommand<Void>("FLUSHALL", new VoidReplayConvertor());
RedisStrictCommand<List<String>> KEYS = new RedisStrictCommand<List<String>>("KEYS", new StringListReplayDecoder());
RedisCommand<Boolean> HSET = new RedisCommand<Boolean>("HSET", new BooleanReplayConvertor(), 2, ValueType.MAP);
RedisStrictCommand<String> HINCRBYFLOAT = new RedisStrictCommand<String>("HINCRBYFLOAT");
RedisCommand<MapScanResult<Object, Object>> HSCAN = new RedisCommand<MapScanResult<Object, Object>>("HSCAN", new NestedMultiDecoder(new ObjectMapReplayDecoder(), new MapScanResultReplayDecoder()), ValueType.MAP);
RedisCommand<Map<Object, Object>> HGETALL = new RedisCommand<Map<Object, Object>>("HGETALL", new ObjectMapReplayDecoder(), ValueType.MAP);
RedisCommand<List<Object>> HVALS = new RedisCommand<List<Object>>("HVALS", new ObjectListReplayDecoder<Object>(), ValueType.MAP_VALUE);
RedisCommand<Boolean> HEXISTS = new RedisCommand<Boolean>("HEXISTS", new BooleanReplayConvertor(), 2, ValueType.MAP_KEY);
RedisStrictCommand<Integer> HLEN = new RedisStrictCommand<Integer>("HLEN", new IntegerReplayConvertor());
RedisCommand<Set<Object>> HKEYS = new RedisCommand<Set<Object>>("HKEYS", new ObjectSetReplayDecoder(), ValueType.MAP_KEY);
RedisCommand<String> HMSET = new RedisCommand<String>("HMSET", new StringReplayDecoder(), 1, ValueType.MAP);
RedisCommand<List<Object>> HMGET = new RedisCommand<List<Object>>("HMGET", new ObjectListReplayDecoder<Object>(), 2, ValueType.MAP_KEY, ValueType.MAP_VALUE);
RedisCommand<Object> HGET = new RedisCommand<Object>("HGET", 2, ValueType.MAP_KEY, ValueType.MAP_VALUE);
RedisCommand<Long> HDEL = new RedisStrictCommand<Long>("HDEL", 2, ValueType.MAP_KEY);
RedisStrictCommand<Long> DEL = new RedisStrictCommand<Long>("DEL");
RedisStrictCommand<Boolean> DEL_SINGLE = new RedisStrictCommand<Boolean>("DEL", new BooleanReplayConvertor());
RedisCommand<Object> GET = new RedisCommand<Object>("GET");
RedisCommand<Void> SET = new RedisCommand<Void>("SET", new VoidReplayConvertor(), 2);
RedisCommand<Boolean> SETNX = new RedisCommand<Boolean>("SETNX", new BooleanReplayConvertor(), 2);
RedisCommand<Void> SETEX = new RedisCommand<Void>("SETEX", new VoidReplayConvertor(), 3);
RedisStrictCommand<Boolean> EXISTS = new RedisStrictCommand<Boolean>("EXISTS", new BooleanReplayConvertor());
RedisStrictCommand<Boolean> RENAMENX = new RedisStrictCommand<Boolean>("RENAMENX", new BooleanReplayConvertor());
RedisStrictCommand<Void> RENAME = new RedisStrictCommand<Void>("RENAME", new VoidReplayConvertor());
RedisStrictCommand<Boolean> MOVE = new RedisStrictCommand<Boolean>("MOVE", new BooleanReplayConvertor());
RedisStrictCommand<Void> MIGRATE = new RedisStrictCommand<Void>("MIGRATE", new VoidReplayConvertor());
RedisCommand<Long> PUBLISH = new RedisCommand<Long>("PUBLISH", 2);
RedisCommand<Object> SUBSCRIBE = new RedisCommand<Object>("SUBSCRIBE", new PubSubStatusDecoder());
RedisCommand<Object> UNSUBSCRIBE = new RedisCommand<Object>("UNSUBSCRIBE", new PubSubStatusDecoder());
RedisCommand<Object> PSUBSCRIBE = new RedisCommand<Object>("PSUBSCRIBE", new PubSubStatusDecoder());
RedisCommand<Object> PUNSUBSCRIBE = new RedisCommand<Object>("PUNSUBSCRIBE", new PubSubStatusDecoder());
RedisStrictCommand<String> CLUSTER_NODES = new RedisStrictCommand<String>("CLUSTER", "NODES", new StringDataDecoder());
RedisStrictCommand<Map<String, String>> CLUSTER_INFO = new RedisStrictCommand<Map<String, String>>("CLUSTER", "INFO", new StringMapDataDecoder());
RedisStrictCommand<List<String>> SENTINEL_GET_MASTER_ADDR_BY_NAME = new RedisStrictCommand<List<String>>("SENTINEL", "GET-MASTER-ADDR-BY-NAME", new StringListReplayDecoder());
RedisStrictCommand<List<Map<String, String>>> SENTINEL_SLAVES = new RedisStrictCommand<List<Map<String, String>>>("SENTINEL", "SLAVES", new StringMapReplayDecoder());
}
4. 命令执行数据 CommandData
类用于封装一个 Redis 命令的所有相关数据,包括命令本身、参数、编码解码器以及异步结果处理。
package org.redisson.client.protocol;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.redisson.client.codec.Codec;
import org.redisson.client.protocol.decoder.MultiDecoder;
import io.netty.util.concurrent.Promise;
public class CommandData<T, R> implements QueueCommand {
final Promise<R> promise; // 表示异步操作的结果
final RedisCommand<T> command; // 要执行的 Redis 命令
final Object[] params; // Redis命令参数
final Codec codec; // 编解码器
final MultiDecoder<Object> messageDecoder; // 处理 Redis 返回的复杂响应解码器。 比如 MULTI 命令的结果
public CommandData(Promise<R> promise, Codec codec, RedisCommand<T> command, Object[] params) {
this(promise, null, codec, command, params);
}
public CommandData(Promise<R> promise, MultiDecoder<Object> messageDecoder, Codec codec, RedisCommand<T> command, Object[] params) {
this.promise = promise;
this.command = command;
this.params = params;
this.codec = codec;
this.messageDecoder = messageDecoder;
}
public RedisCommand<T> getCommand() {
return command;
}
public Object[] getParams() {
return params;
}
public MultiDecoder<Object> getMessageDecoder() {
return messageDecoder;
}
public Promise<R> getPromise() {
return promise;
}
public Codec getCodec() {
return codec;
}
@Override
public String toString() {
return "CommandData [promise=" + promise + ", command=" + command + ", params="
+ Arrays.toString(params) + ", codec=" + codec + "]";
}
@Override
public List<CommandData<Object, Object>> getPubSubOperations() {
// 如果是发布订阅相关的命令,才会有返回值
if (Arrays.asList("PSUBSCRIBE", "SUBSCRIBE", "PUNSUBSCRIBE", "UNSUBSCRIBE")
.contains(getCommand().getName())) {
return Collections.singletonList((CommandData<Object, Object>)this);
}
return Collections.emptyList();
}
}
5. 一组命令执行数据 CommandsData
封装一组 Redis 命令,支持批量处理。 在Redisson库中用于执行多个命令的场景。
package org.redisson.client.protocol;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import io.netty.util.concurrent.Promise;
public class CommandsData implements QueueCommand {
private final List<CommandData<?, ?>> commands; // 存储一批命令
private final Promise<Void> promise; // 异步操作的结果
public CommandsData(Promise<Void> promise, List<CommandData<?, ?>> commands) {
super();
this.promise = promise;
this.commands = commands;
}
public Promise<Void> getPromise() {
return promise;
}
public List<CommandData<?, ?>> getCommands() {
return commands;
}
@Override
public List<CommandData<Object, Object>> getPubSubOperations() {
// 储符合条件的 CommandData 对象
List<CommandData<Object, Object>> result = new ArrayList<CommandData<Object, Object>>();
for (CommandData<?, ?> commandData : commands) {
// 检查当前命令是否是订阅或取消订阅命令
if (Arrays.asList("PSUBSCRIBE", "SUBSCRIBE", "PUNSUBSCRIBE", "UNSUBSCRIBE")
.equals(commandData.getCommand().getName())) {
result.add((CommandData<Object, Object>)commandData);
}
}
// 返回符合条件的数据
return result;
}
}