I currently have a JMSListener as shown below. It uses a selector of a value in a properties file. This works fine.
@JmsListener(destination = "myQueueDest",
selector = MyHeaders.SELECTOR_KEY + " = '${myapp.selector_val}'")
private void consumeData(MyCustomObj mycustomObj) { }
I have a need now to use a dynamic selector with a value in memory, rather than the spring property. Is there a way to use JMSListener (or some other listener mechnaism) to do a selection off the ActiveMQ queue?
Update:
It may be possible to assign an ID to my @JMSListener, and then retrieve it from my JmsListenerEndpointRegistry bean. Get the listener container by ID, cast it to DefaultMessageListenerContainer, and call setMessageSelector(), although I'm not entirely sure if this will work yet.
This requires setting my DefaultJmsListenerContainerFactory bean to have the cache level of CACHE_SESSION.
But this doesn't seem to work, as the listener picks up all messages, regardless of what I set the message selector to be.
As stated in one of the comments:
the javadoc for setMessageSelector says it can be set at runtime. http://docs.spring.io/spring-framework/docs/2.5.x/api/org/springframework/jms/listener/AbstractMessageListenerContainer.html#setMessageSelector(java.lang.String)
This example explains how to setup at startup but doing it dynamically should be possible with a few more tricks:
@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;
}
}
And the 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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With