溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

RespCommand的使用方法

發(fā)布時(shí)間:2021-07-10 10:30:02 來源:億速云 閱讀:122 作者:chen 欄目:大數(shù)據(jù)

本篇內(nèi)容主要講解“RespCommand的使用方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“RespCommand的使用方法”吧!

本文主要研究一下RespCommand

RespCommand

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

@FunctionalInterface
public interface RespCommand {
  RedisToken execute(Request request);
}
  • RespCommand定義了execute方法,接收Request參數(shù),返回RedisToken

Request

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

public interface Request {
  String getCommand();
  ImmutableArray<SafeString> getParams();
  SafeString getParam(int i);
  Option<SafeString> 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<SafeString> params;

  private final Session session;

  private final ServerContext server;

  public DefaultRequest(ServerContext server, Session session, SafeString command, ImmutableArray<SafeString> 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<SafeString> getParams() {
    return params;
  }

  @Override
  public SafeString getParam(int i) {
    if (i < params.size()) {
      return params.get(i);
    }
    return null;
  }

  @Override
  public Option<SafeString> 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實(shí)現(xiàn)了Request接口,它定義了command、params、session、server屬性,均在構(gòu)造器中傳入

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<String, Class<?>> metadata = new HashMap<>();
  private final Map<String, RespCommand> 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<? extends Annotation> 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的構(gòu)造器添加了PingCommand、EchoCommand、QuitCommand、TimeCommand四個(gè)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實(shí)現(xiàn)了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會(huì)讀取ParamLength注解,若讀的到則將注解的value值賦值給params,用于execute方法對(duì)request的參數(shù)長(zhǎng)度進(jìn)行校驗(yàn)

小結(jié)

RespCommand定義了execute方法,接收Request參數(shù),返回RedisToken;CommandSuite的構(gòu)造器添加了PingCommand、EchoCommand、QuitCommand、TimeCommand四個(gè)command;addCommand方法將factory.wrap(command)的命令放入commands中;DefaultCommandWrapperFactory實(shí)現(xiàn)了CommandWrapperFactory接口,其wrap方法使用CommandWrapper包裝RespCommand;CommandWrapper會(huì)讀取ParamLength注解,若讀的到則將注解的value值賦值給params,用于execute方法對(duì)request的參數(shù)長(zhǎng)度進(jìn)行校驗(yàn)

到此,相信大家對(duì)“RespCommand的使用方法”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI