千家信息网

RespCommand的使用方法

发表于:2024-09-24 作者:千家信息网编辑
千家信息网最后更新 2024年09月24日,本篇内容主要讲解"RespCommand的使用方法",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"RespCommand的使用方法"吧!序本文主要研究一下R
千家信息网最后更新 2024年09月24日RespCommand的使用方法

本篇内容主要讲解"RespCommand的使用方法",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"RespCommand的使用方法"吧!

本文主要研究一下RespCommand

RespCommand

resp-server-0.16.0/src/main/java/com/github/tonivade/resp/command/RespCommand.java

@FunctionalInterfacepublic interface RespCommand {  RedisToken execute(Request request);}
  • RespCommand定义了execute方法,接收Request参数,返回RedisToken

Request

resp-server-0.16.0/src/main/java/com/github/tonivade/resp/command/Request.java

public interface Request {  String getCommand();  ImmutableArray getParams();  SafeString getParam(int i);  Option getOptionalParam(int i);  int getLength();  boolean isEmpty();  Session getSession();  ServerContext getServerContext();  boolean isExit();}
  • Request接口定义了getCommand、getParams、getParam、getOptionalParam、getLength、isEmpty、getSession、getServerContext、isExit方法

DefaultRequest

resp-server-0.16.0/src/main/java/com/github/tonivade/resp/command/DefaultRequest.java

public class DefaultRequest implements Request {  private final SafeString command;  private final ImmutableArray params;  private final Session session;  private final ServerContext server;  public DefaultRequest(ServerContext server, Session session, SafeString command, ImmutableArray params) {    this.server = server;    this.session = session;    this.command = requireNonNull(command);    this.params = requireNonNull(params);  }  @Override  public String getCommand() {    return command.toString();  }  @Override  public ImmutableArray getParams() {    return params;  }  @Override  public SafeString getParam(int i) {    if (i < params.size()) {      return params.get(i);    }    return null;  }  @Override  public Option getOptionalParam(int i) {    return Option.of(() -> getParam(i));  }  @Override  public int getLength() {    return params.size();  }  @Override  public boolean isEmpty() {    return params.isEmpty();  }  @Override  public boolean isExit() {    return command.toString().equalsIgnoreCase("quit");  }  @Override  public Session getSession() {    return session;  }  @Override  public ServerContext getServerContext() {    return server;  }  @Override  public String toString() {    return command + "[" + params.size() + "]: " + params;  }}
  • DefaultRequest实现了Request接口,它定义了command、params、session、server属性,均在构造器中传入

CommandSuite

resp-server-0.16.0/src/main/java/com/github/tonivade/resp/command/CommandSuite.java

public class CommandSuite {  private static final Logger LOGGER = LoggerFactory.getLogger(CommandSuite.class);  private final Map> metadata = new HashMap<>();  private final Map commands = new HashMap<>();  private final NullCommand nullCommand = new NullCommand();  private final CommandWrapperFactory factory;  public CommandSuite() {    this(new DefaultCommandWrapperFactory());  }  public CommandSuite(CommandWrapperFactory factory) {    this.factory = factory;    addCommand(PingCommand.class);    addCommand(EchoCommand.class);    addCommand(QuitCommand.class);    addCommand(TimeCommand.class);  }  public RespCommand getCommand(String name) {    return commands.getOrDefault(name.toLowerCase(), nullCommand);  }  public boolean isPresent(String name, Class annotationClass) {    return getMetadata(name).isAnnotationPresent(annotationClass);  }  public boolean contains(String name) {    return commands.get(name) != null;  }  protected void addCommand(Class clazz) {    Try.of(clazz::newInstance)       .onSuccess(this::processCommand)       .onFailure(e -> LOGGER.error("error loading command: " + clazz.getName(), e));  }  protected void addCommand(String name, RespCommand command) {    commands.put(name.toLowerCase(), factory.wrap(command));  }  private void processCommand(Object command) {    Class clazz = command.getClass();    Command annotation = clazz.getAnnotation(Command.class);    if (annotation != null) {      commands.put(annotation.value(), factory.wrap(command));      metadata.put(annotation.value(), clazz);    } else {      LOGGER.warn("annotation not present at {}", clazz.getName());    }  }  private Class getMetadata(String name) {    return metadata.getOrDefault(name.toLowerCase(), Void.class);  }}
  • CommandSuite的构造器添加了PingCommand、EchoCommand、QuitCommand、TimeCommand四个command;addCommand方法将factory.wrap(command)的命令放入commands中

CommandWrapperFactory

resp-server-0.16.0/src/main/java/com/github/tonivade/resp/command/CommandWrapperFactory.java

public interface CommandWrapperFactory {  RespCommand wrap(Object command);}
  • CommandWrapperFactory定义了wrap方法,将command包装为RespCommand

DefaultCommandWrapperFactory

resp-server-0.16.0/src/main/java/com/github/tonivade/resp/command/DefaultCommandWrapperFactory.java

public class DefaultCommandWrapperFactory implements CommandWrapperFactory {  @Override  public RespCommand wrap(Object command) {    if (command instanceof RespCommand) {      return new CommandWrapper((RespCommand) command);    }    throw new IllegalArgumentException("must implements command interface");  }}
  • DefaultCommandWrapperFactory实现了CommandWrapperFactory接口,其wrap方法使用CommandWrapper包装RespCommand

CommandWrapper

resp-server-0.16.0/src/main/java/com/github/tonivade/resp/command/CommandWrapper.java

public class CommandWrapper implements RespCommand {  private int params;  private final RespCommand command;  public CommandWrapper(RespCommand command) {    this.command = command;    ParamLength length = command.getClass().getAnnotation(ParamLength.class);    if (length != null) {      this.params = length.value();    }  }  @Override  public RedisToken execute(Request request) {    if (request.getLength() < params) {      return error("ERR wrong number of arguments for '" + request.getCommand() + "' command");    }    return command.execute(request);  }}
  • CommandWrapper会读取ParamLength注解,若读的到则将注解的value值赋值给params,用于execute方法对request的参数长度进行校验

小结

RespCommand定义了execute方法,接收Request参数,返回RedisToken;CommandSuite的构造器添加了PingCommand、EchoCommand、QuitCommand、TimeCommand四个command;addCommand方法将factory.wrap(command)的命令放入commands中;DefaultCommandWrapperFactory实现了CommandWrapperFactory接口,其wrap方法使用CommandWrapper包装RespCommand;CommandWrapper会读取ParamLength注解,若读的到则将注解的value值赋值给params,用于execute方法对request的参数长度进行校验

到此,相信大家对"RespCommand的使用方法"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0