我目前有一个JMSListener,如下所示。它使用属性文件中值的选择器。这很好。
@JmsListener(destination = "myQueueDest",
selector = MyHeaders.SELECTOR_KEY + " = '${myapp.selector_val}'")
private void consumeData(MyCustomObj mycustomObj) { }
我现在需要在内存中使用带有值的动态选择器,而不是spring属性。有没有办法使用JMSListener(或其他一些监听器mechnaism)从ActiveMQ队列中进行选择?
更新
可以为我的@JMSListener
分配一个ID,然后从我的JmsListenerEndpointRegistry
bean中检索它。按ID获取侦听器容器,将其强制转换为DefaultMessageListenerContainer
,然后调用setMessageSelector()
,但我还不完全确定这是否可行。
这需要将我的DefaultJmsListenerContainerFactory bean设置为具有CACHE_SESSION
的缓存级别。
但这似乎不起作用,因为无论我将消息选择器设置为什么,侦听器都会接收所有消息。
答案 0 :(得分:0)
JMS规范说明在创建消费者时必须提供选择字符串。所以答案是否定的。必须使用不同的选择字符串关闭和重新创建使用者,以接收符合不同选择标准的消息。
如果您的项目不是必须使用JMS API,那么您可以使用Active MQ的本机API进行探索。我确信每次调用receive时API都会有一种指定不同选择字符串的方法。 IBM MQ的本机API提供了这样的功能。
答案 1 :(得分:0)
如其中一条评论中所述:
setMessageSelector的javadoc说它可以在运行时设置。 http://docs.spring.io/spring-framework/docs/2.5.x/api/org/springframework/jms/listener/AbstractMessageListenerContainer.html#setMessageSelector(java.lang.String)
这个例子解释了如何在启动时进行设置,但是可以通过一些技巧来动态地进行设置:
@EnableJms
@Configuration
public class JmsConfiguration {
@Value("${my.int.param:100}")
private int config;
@Bean
public MessageConverter messageConverter() {
final MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
@Bean
public JmsListenerContainerFactory<?> specialQueueListenerFactory() {
final String selector = "foo > " + config;
final DefaultJmsListenerContainerFactory factory = new CustomJmsListenerContainerFactory(selector);
factory.setMessageConverter(messageConverter());
return factory;
}
}
CustomJmsListenerContainerFactory
public class CustomJmsListenerContainerFactory extends DefaultJmsListenerContainerFactory {
private final String selector;
public CustomJmsListenerContainerFactory(String jmsSelector) {
this.selector = jmsSelector;
}
@Override
public DefaultMessageListenerContainer createListenerContainer(JmsListenerEndpoint endpoint) {
final DefaultMessageListenerContainer instance = super.createListenerContainer(endpoint);
instance.setMessageSelector(selector);
return instance;
}
}