在使用出站 jms 适配器时,我们可以 select 基于 MessageHeaders 动态地使用 JmsTemplate 吗?
Can we select JmsTemplate dynamically on the basis of MessageHeaders while using outbound jms adapter?
我已经创建了 2 个 jmsTemplate
Bean,以便能够相应地处理向 Solace Queue
和 Solace Topic
发送消息,现在当我在 exampleChannel
上传递消息时下面我想知道 MessageHandler 是否可以动态选择 jmsTemplate ?如果我用 MessageHeader
传递消息让我们说 destinationType=Topic/Queue
配置如下
@Autowired
@Qualifier("topic")
private JmsTemplate jmsTemplate;
@Autowired
@Qualifier("queue")
private JmsTemplate jmsTemplate1;
@Bean
@ServiceActivator(inputChannel = "exampleMessageChannel" )
public MessageHandler archiveOutboundHandler() {
/*
I need to select between jmsTemplate & jmsTemplate1 on the basis on header
information.
**/
JmsSendingMessageHandler messageHandler = new JmsSendingMessageHandler(jmsTemplete);
messageHandler.setDestinationExpression(new FunctionExpression<Message<?>>(m->m.getHeaders().get("destination")));
return messageHandler;
}
可能吗?或者有更好的方法吗?
更新 1:
在@Artem 建议将 destinationExpression 的实现更改为 return Destination 之后,我这样做了
@Bean
@ServiceActivator(inputChannel = "outMessageChannel" )
public MessageHandler archiveOutboundHandler() {
JmsSendingMessageHandler messageHandler = new JmsSendingMessageHandler(jmsTemplate);
messageHandler.setDestinationExpression(new FunctionExpression<Message<?>>(message -> {
if((Objects.equals(message.getHeaders().get("destinationType"), "topic"))){
return (Topic) () -> (String) message.getHeaders().get("destination");
}else{
return (Queue) () -> (String) message.getHeaders().get("destination");
}
}));
return messageHandler;
}
我低于异常
$$Lambda1/1572602632 cannot be cast to com.solacesystems.jms.SolDestination)
更新 2
我能够使用 JndiDestinationResolver
解析目的地
正如 Artem 建议使用 BeanFactoryDestinationResolver
那样,我使用它是不可行的,因为目的地太多并且 BeanFactoryDestinationResolver
需要为每个目的地创建特定的 bean。
我已经配置了 JndiDestinationResolver
所以我只需要注入 DestinationResolver
来解析目标。
下面是片段,
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private DestinationResolver destinationResolver;
@Bean
@ServiceActivator(inputChannel = "exampleChannel" )
public MessageHandler jmsOutboundHandler() {
JmsSendingMessageHandler messageHandler = new JmsSendingMessageHandler(jmsTemplate);
messageHandler.setDestinationExpression(new FunctionExpression<Message<?>>(message -> {
if(message.getHeaders().get("dest_type").equals("topic")){
return destinationResolver.resolveDestinationName(null,(String) message.getHeaders().get("dest"),true);
}else{
return destinationResolver.resolveDestinationName(null,(String) message.getHeaders().get("dest"),false);
}
}));
return messageHandler;
}
感谢所有意见,我将提出 GH 问题以在 DynamicJmsTemplate
中包含 pubsub 功能
我明白你的意思了。
它的逻辑是这样的:
protected Destination resolveDestinationName(Session session, String destinationName) throws JMSException {
return getDestinationResolver().resolveDestinationName(session, destinationName, isPubSubDomain());
}
默认 DynamicDestinationResolver
是这样的:
if (pubSubDomain) {
return resolveTopic(session, destinationName);
}
else {
return resolveQueue(session, destinationName);
}
作为解决方法,考虑让 destinationExpression
被评估为 javax.jms.Destination
实例而不是它们的普通名称。这样你就不会被束缚在 pubSubDomain
属性.
还有一个 BeanFactoryDestinationResolver
可以将提供的名称从应用程序上下文解析为 Destination
bean。
同时,我要求您提出一个 GH 问题,以便将 pubSubDomain
支持添加到 DynamicJmsTemplate
API。因此,您将能够根据 JmsSendingMessageHandler
.
中的表达式求值来确定 pubSubDomain
我已经创建了 2 个 jmsTemplate
Bean,以便能够相应地处理向 Solace Queue
和 Solace Topic
发送消息,现在当我在 exampleChannel
上传递消息时下面我想知道 MessageHandler 是否可以动态选择 jmsTemplate ?如果我用 MessageHeader
传递消息让我们说 destinationType=Topic/Queue
配置如下
@Autowired
@Qualifier("topic")
private JmsTemplate jmsTemplate;
@Autowired
@Qualifier("queue")
private JmsTemplate jmsTemplate1;
@Bean
@ServiceActivator(inputChannel = "exampleMessageChannel" )
public MessageHandler archiveOutboundHandler() {
/*
I need to select between jmsTemplate & jmsTemplate1 on the basis on header
information.
**/
JmsSendingMessageHandler messageHandler = new JmsSendingMessageHandler(jmsTemplete);
messageHandler.setDestinationExpression(new FunctionExpression<Message<?>>(m->m.getHeaders().get("destination")));
return messageHandler;
}
可能吗?或者有更好的方法吗?
更新 1:
在@Artem 建议将 destinationExpression 的实现更改为 return Destination 之后,我这样做了
@Bean
@ServiceActivator(inputChannel = "outMessageChannel" )
public MessageHandler archiveOutboundHandler() {
JmsSendingMessageHandler messageHandler = new JmsSendingMessageHandler(jmsTemplate);
messageHandler.setDestinationExpression(new FunctionExpression<Message<?>>(message -> {
if((Objects.equals(message.getHeaders().get("destinationType"), "topic"))){
return (Topic) () -> (String) message.getHeaders().get("destination");
}else{
return (Queue) () -> (String) message.getHeaders().get("destination");
}
}));
return messageHandler;
}
我低于异常
$$Lambda1/1572602632 cannot be cast to com.solacesystems.jms.SolDestination)
更新 2
我能够使用 JndiDestinationResolver
正如 Artem 建议使用 BeanFactoryDestinationResolver
那样,我使用它是不可行的,因为目的地太多并且 BeanFactoryDestinationResolver
需要为每个目的地创建特定的 bean。
我已经配置了 JndiDestinationResolver
所以我只需要注入 DestinationResolver
来解析目标。
下面是片段,
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private DestinationResolver destinationResolver;
@Bean
@ServiceActivator(inputChannel = "exampleChannel" )
public MessageHandler jmsOutboundHandler() {
JmsSendingMessageHandler messageHandler = new JmsSendingMessageHandler(jmsTemplate);
messageHandler.setDestinationExpression(new FunctionExpression<Message<?>>(message -> {
if(message.getHeaders().get("dest_type").equals("topic")){
return destinationResolver.resolveDestinationName(null,(String) message.getHeaders().get("dest"),true);
}else{
return destinationResolver.resolveDestinationName(null,(String) message.getHeaders().get("dest"),false);
}
}));
return messageHandler;
}
感谢所有意见,我将提出 GH 问题以在 DynamicJmsTemplate
我明白你的意思了。
它的逻辑是这样的:
protected Destination resolveDestinationName(Session session, String destinationName) throws JMSException {
return getDestinationResolver().resolveDestinationName(session, destinationName, isPubSubDomain());
}
默认 DynamicDestinationResolver
是这样的:
if (pubSubDomain) {
return resolveTopic(session, destinationName);
}
else {
return resolveQueue(session, destinationName);
}
作为解决方法,考虑让 destinationExpression
被评估为 javax.jms.Destination
实例而不是它们的普通名称。这样你就不会被束缚在 pubSubDomain
属性.
还有一个 BeanFactoryDestinationResolver
可以将提供的名称从应用程序上下文解析为 Destination
bean。
同时,我要求您提出一个 GH 问题,以便将 pubSubDomain
支持添加到 DynamicJmsTemplate
API。因此,您将能够根据 JmsSendingMessageHandler
.
pubSubDomain