Spring Boot 2.3.1.RELEASE.
With spring.jms.cache.enabled=true
(default), Spring creates a CachingConnectionFactory
:
@ConditionalOnProperty(prefix = "spring.jms.cache", name = "enabled", havingValue = "true",
matchIfMissing = true)
static class CachingConnectionFactoryConfiguration {
This is bad since it shouldn't be used with DefaultMessageListenerContainer
. I think it's the reason why some of my messages get "lost" until they suddenly reappear.
With spring.jms.cache.enabled=false
, Spring creates an ActiveMQConnectionFactory
:
@ConditionalOnProperty(prefix = "spring.jms.cache", name = "enabled", havingValue = "false")
ActiveMQConnectionFactory jmsConnectionFactory(ActiveMQProperties properties,
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers) {
return createJmsConnectionFactory(properties, factoryCustomizers);
}
private static ActiveMQConnectionFactory createJmsConnectionFactory(ActiveMQProperties properties,
This is bad because with each poll, it creates a new connection to the Broker - flooding my broker with hundreds of connections.
So I though the solution to my problems is to use a SingleConnectionFactory
. In AbstractPollingMessageListenerContainer.MessageListenerContainerResourceFactory
I saw:
public Connection createConnection() throws JMSException {
if (AbstractPollingMessageListenerContainer.this.sharedConnectionEnabled()) {
Connection sharedCon = AbstractPollingMessageListenerContainer.this.getSharedConnection();
return new SingleConnectionFactory(sharedCon).createConnection();
}
So I thought I would just:
Jms.channel(connectionFactory)
.cacheLevel(DefaultMessageListenerContainer.CACHE_CONNECTION)
but as it turns out, this method is never called, only JmsAccessor.createConnection()
is which creates an ActiveMQConnectionFactory
. My cache level has no effect.
So how do I use SingleConnectionFactory
properly?