我可以将多种类型的实例写入给定目的地,例如:
JmsTemplate template = ...
Alpha alpha = new Alpha(...);
Beta beta = new Beta(...);
template.convertAndSend("my-destination", alpha);
template.convertAndSend("my-destination", beta);
我以为我能够提供多个@JmsListener
带注释的方法来接收不同的消息有效负载 - 如下所示:
@JmsListener(destination = "my-destination")
public void receiveAlpha(Alpha alpha) { ... }
@JmsListener(destination = "my-destination")
public void receiveBeta(Beta beta) { ... }
但是,如果我尝试这样做,我会在PayloadArgumentResolver.resolveArgument
中获得例外,因为它无法区分应将Beta
值发送到一个方法而将Alpha
值发送给另一个方法。
我该如何处理?当我将有效负载类型编码为消息属性时,我可以指定一个选择器来使事情正常工作:
@JmsListener(destination = "my-destination", selector = "_type = 'Alpha'")
public void receiveAlpha(Alpha alpha) { ... }
@JmsListener(destination = "my-destination", selector = "_type = 'Beta'")
public void receiveBeta(Beta beta) { ... }
但是,由于Spring在幕后做了各种各样的聪明,我很惊讶我必须明确地帮助它。
有更隐式/更好的方法吗?
答案 0 :(得分:3)
JmsListener
没有方法支持路由 - 每个带注释的方法都有自己的侦听器容器。
唯一的另一种选择是使用...(Object object)
并自己投降。
答案 1 :(得分:1)
尝试在消息后处理器中设置selector属性。在consumer方法中使用与selector相同的属性。请检查此JMSListener selector not working
发送到队列:
template.convertAndSend("my-destination", alpha, m -> {
m.setStringProperty("classType", "alpha");
return m;
});
从队列中接收消息:
@JmsListener(destination = "my-destination", selector = "classType = 'alpha'")<br/>
public void receiveAlpha(Alpha alpha) { ... }
答案 2 :(得分:0)
您可以设置JmsTemplate的消息转换器,以将消息的Java类型设置为消息的“ type”属性,然后在JmsListener中,将选择器配置为仅接收所需的消息类型。
下面是Kotlin中的一个示例,Java应该是相同的
默认消息转换,将消息类型注释为“ type”属性:
@Bean // Serialize message content to json using TextMessage
fun jacksonJmsMessageConverter(): MessageConverter {
val converter = MappingJackson2MessageConverter()
converter.setTargetType(MessageType.TEXT)
converter.setTypeIdPropertyName("type")
return converter
}
使用带注释的消息转换器,JMS侦听器可以在选择器中指定消息类型:
// Uses default JmsListenerContainerFactory
@JmsListener(destination = "mailbox", containerFactory = "myFactory", selector="type='com.garnetsoft.sf.service.queue.CopyFolderJob'")
fun receiveMessage(job: CopyFolderJob) {
println("Received copy job <$job>")
}
@JmsListener(destination = "mailbox", containerFactory = "myFactory", selector="type='com.garnetsoft.sf.service.queue.CutFolderJob'")
fun receiveMessage(job: CutFolderJob) {
println("Received cut job <$job>")
}
希望这会有所帮助。