【发布时间】:2016-07-25 08:49:15
【问题描述】:
所以我们在 spring-amqp 中使用漂亮的 @RabbitHandler 注释来创建类似于 RestControllers 的编码风格但在引擎盖下与 Rabbit 一起工作的端点。这一切都非常好和整洁,并且特别适用于基于签名的方法处理程序的动态解析。然而,我们在这里面临一些争议。 所以想象下面的方法
@RabbitHandler
public void handleEmailDto(EmailDto message) {
System.out.println(message);
}
这将由 MessagingMessageConverter.java 类的 fromMessage 方法处理。在链下的某个点,将需要消息的类型信息,以便处理程序解析器确定使用消息的有效负载调用哪个方法,以及将有效负载序列化到哪个类。问题是我们正在使用 MappingJackson2MessageConverter。然而,我们需要一个填充的消息的____TypeId____ 属性以及类类型的完全限定名称。那也不是问题。精心设计和深思熟虑。
当这个类不在类路径上时,问题就来了。这对我们来说实际上是一个巨大的痛苦,因为我们在微服务环境中工作,并且我们的一些服务是完全解耦的。也就是说..我们不希望拥有保存我们数据域的“通用”人工制品,这样我们就可以在运行时在消息的发送者和接收者中使用它。我跟踪了代码,看到了这种孔类型的情况是如何处理的,以及为什么会这样处理。
但是从架构的角度来看,这是非常有限的......这是否意味着我们肯定需要在完全解耦的微服务之间共享代码,否则只是为了满足序列化/反序列化/方法解析逻辑?
也许我遗漏了某些东西或忽略了另一种方法。如果是这样的话,我当然愿意接受建议。提前感谢您的帮助。
【问题讨论】:
-
听起来您可以尝试使用 java lang 本身的内部类型,而不是自定义类型。因为您不会跨服务共享这些类。如果我们称其为模式,则服务之间应该相同。既然您不共享这些类,您也不应该使用它们。我的 seggestion 使用的是内部类型,例如
java.lang.Map或java.lang.List。但是,您需要做更具体的工作才能获得那里的属性。顺便说一句,无论您从网络传输什么,如果它们不是单一的原始类型,您都可以将其放入映射中。它对你来说足够智能。 -
我不太明白你所说的背后的逻辑。我正在尝试使用一些数据并将其解析为一个对象。当你点击一个休息控制器时,你不需要与服务器共享相同的类型,是吗?
-
是的,你是对的。我要说的是,您可以读取数据并将它们反序列化为映射,而不是将数据反序列化为自定义的类类型。例如,你的远程服务返回一个序列化的
A(以json为例),其中A代表自定义的类类型(不是单一的简单类型,例如long),然后你可以将其反序列化为映射不是新的A实例。最后,您可以从此地图中获取属性。你明白我在说什么吗? -
是的,我完全明白你在说什么,事实上我们已经考虑过了。然而这对我们来说是不可行的。这个注释的目的是让事情变得简单。当我说事情时,我的意思是基于类型信息等的方法处理推理。我没有看到在每个“处理程序”方法上传递 JsonNode 对象或字符串,从而产生非常可读和可维护的代码。不过我同意你的看法。它只是不是我们正在寻找的解决方案。
标签: java spring rabbitmq spring-amqp