如何通过 JMS 发送 Kryo 序列化对象?

How to send Kryo serialized objects over JMS?

我想使用 Kryo 来(反)序列化对象并通过 JMS send/receive它们。

我遇到的问题是发送方和接收方都必须使用相同的 ID 注册 类。

Kryo 有一个我使用的方法 register (Class type, int id)。不幸的是 id 是一个 int(与 Serializable 接口使用的 long serialVersionUID 相比)。如果我可以使用 serialVersionUID 注册 类.

就好了

你们是如何通过网络使用 Kryo 的?

您不必在每个 class 想要使用 Kryo 序列化时显式注册。注册 classes 的主要好处是:

  • 性能:Kryo 第一次看到 class 时,它会生成一个 ID 并在序列化流中发送此 ID,并使用 class 的名称。下一次,Kryo 只发送 ID,没有发送姓名。如果 class 被显式注册,则 ID 已知,Kryo 永远不会发送 class 的名称:您在输出流中获得了一些字节
  • 一些"security":如果你设置了"registration required"标志,Kryo将不会发送它不知道的class。然后您可以过滤通过网络发送的数据

但是,当您注册 class 时,您必须在所有地方以相同的顺序注册完全相同的 classes。这并不总是可能的。

在您的例子中,JMS 规范没有定义任何关于 classes 序列化的内容。这将取决于您使用的实现。如果你想要一些可移植的东西,你可以在应用层这样做:

  • 使用 Kryo 将您的 classes 序列化为字节数组
  • 使用 BytesMessage
  • 通过 JMS 发送此字节数组
  • 在您的 MessageListener 中使用 Kryo
  • 反序列化消息

因为你可以控制谁 serialize/deserialize,你可以在这里注册你使用的 classes,或者让 Kryo 自己生成 ID

ActiveMQ 不支持自定义序列化挂钩。您无法插入自己的序列化实现,因此无法告诉 ActiveMQ 在发送 ObjectMessage 时使用 Kryo(请参阅 ActiveMQObjectMessage)。您必须使用此 BytesMessage。也许其他 JMS 提供商提供了这样的功能(JMS 只是一个 API 规范,它没有定义消息应该如何 sent/serialized,只有 API 可访问)