嗨,那里有回调!

因为是我的书包,所以我喜欢JavaScript 。 实际上,我已经开始喜欢JavaScritp的面向异步回调的编程风格 。 因此,当我发现自己处于非JavaScript环境中时(例如Java) ,我往往会错过使用回调的机会。 打回来

好消息是您可以在Java中模拟异步回调。 实际上,我最近在一个我称为Ahoy的图书馆中做到了 ,这是适用于AWS的Java SQS库的异步SQS适配器

对于初学者来说, SQS是一个基于云的消息传递平台 –使用SQS,您可以创建队列并将消息放入这些队列,然后可以稍后或通过其他某个过程或相同的确切过程读取这些消息。 所有这些都利用Amazon的大规模冗余架构在面对并发访问时提供了极高的可用性。

Java中的异步回调可以通过两个功能实现:匿名类(包含一个方法)和Java的java.util.concurrent包。

因为Java不允许您轻松地将函数(或方法)作为参数传递,以模拟回调,所以您可以创建一个包含一个方法的接口,该方法基本上模仿一个函数。 对于Ahoy,有两个接口: MessageSendCallbackMessageReceivedCallback –都有一个方法:分别是onSendonReceive 。 因此,Ahoy!的主要类被称为SQSAdapterSQSAdapter公开了两个简单的方法: sendreceive并且都采用了它们相关的回调接口。

要理解的最直接的回调是receive方法。 可以想象, receive是为了处理从特定队列接收到消息时的行为。 因此, receive方法定义如下:

SQSAdapter的接收方法
public void receive(final MessageReceivedCallback callback) {}

MessageReceivedCallback接口如下所示:

MessageReceivedCallback接口
public interface MessageReceivedCallback {
    public void onReceive(String messageId, String message);
}

请注意, onReceive方法需要一个消息ID(特定于SQS)和消息本身-在SQS的情况下,它始终是一个String (请记住, String可以容纳您想要的任何内容:JSON,XML,字节序列)等)。

至此,客户淘! 在收到消息时提供消息的预期行为。 此行为可能是将某些内容写入数据库,生成另一条消息,然后将其发送到另一个队列(您命名)。

现在,有趣的部分是Ahoy!的receive方法的实现。 为了实现异步性,我使用了Java的java.util.concurrent包,可悲的是,它似乎不受欢迎。

接收方法的实现与回调被调用
private void receive(final AmazonSQS sqs, final String queueURL, final MessageReceivedCallback callback) {
  pool.execute(new Runnable() {
    public void run() {
      final List<Message> messages = sqs.receiveMessage(
              new ReceiveMessageRequest(queueURL).withMaxNumberOfMessages(10).withWaitTimeSeconds(20)).getMessages();
      if (messages.size() > 0) {
          for (final Message message : messages) {
            callback.onReceive(message.getMessageId(), message.getBody());
            sqs.deleteMessage(new DeleteMessageRequest(queueURL, message.getReceiptHandle()));
          }
      }
    }
  });
}

使用固定的线程池,将创建一个线程,该线程等待消息到达特定队列。 当显示一条消息时,将为每条消息调用传入的MessageReceivedCalledback

有关如何对Ahoy!客户端进行工作的示例,下面是一个测试用例,用于验证回调的执行:

接收方法已实现
final boolean[] wasReceived = {false};
ahoy.receive(new MessageReceivedCallback() {
  public void onReceive(String messageId, String message) {
    wasReceived[0] = true;
    assertNotNull("message id was null", messageId);
    assertEquals("message wasn't " + origMessage, origMessage, message);
  }
});

同样,发送消息也很相似–创建一个新的Runnable实例,该实例发送特定的消息并调用MessageSentCallbackonSend方法中传递的onSend ,并传递新发送的消息的ID。

send方法也是异步的
private void send(final AmazonSQS sqs, final String queueURL, final String message, final MessageSentCallback callback) {
  pool.execute(new Runnable() {
    public void run() {
      SendMessageResult res = sqs.sendMessage(new SendMessageRequest(queueURL, message));
      if (callback != null) {
        callback.onSend(res.getMessageId());
      }
    }
  });
}

顺便说一下,AWS Java SDK 确实提供了一个异步客户端 。 但是,此客户端的实现利用了Java的Futures 。 尽管Futures是一个简洁的概念 ,但Ahoy!的实现比Futures更方便( 至少对我来说以及我使用SQS的方式 ),因为一旦发送或接收消息,就不会涉及任何轮询。

虽然不一定在Java中本地支持回调,但是您可以很好地模拟它们并实现与JavaScript相同的代码简洁性。 而且,如果您需要方便的方法来与AWS SQS进行交互,请给Ahoy! 尝试一下 ! 你能挖出来吗,伙计?

参考: 嗨,那里有回调! 从我们的JCG合作伙伴 Andrew Glover在The Disco Blog博客中获得。

翻译自: https://www.javacodegeeks.com/2013/10/ahoy-there-callbacks.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值