Is "jmsListenerContainerFactory" the default factory used by SimpleJmsListenerEndpoint

9.5k Views Asked by At

I am working with Spring JMS 4.1 to register messages listeners

In my xml configuration file, I have defined a bean named "jmsListenerContainerFactory":

<bean id="jmsListenerContainerFactory"
          class="org.springframework.jms.config.DefaultJmsListenerContainerFactory"...p:concurrency="3-5".../>
  • First question : with Spring 4.x version, isn't it better to declare this factory this way : <jms:listener-container ... />

  • Second and main question : as stated in official doc (24.6.1) : by default, the infrastructure looks for a bean named jmsListenerContainerFactory as the source for the factory to use to create message listener containers. Is it also the case when programmatically registering endpoints this way:

.

SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
endpoint.setDestination("...");
endpoint.setMessageListener(message -> {...});
registrar.registerEndpoint(endpoint);

or do we have to set it explicitly this way for example : registrar.setContainerFactoryBeanName("jmsListenerContainerFactory");

Thanks

2

There are 2 best solutions below

3
On BEST ANSWER

I don't understand your first question; in the first case, you are defining a DefaultJmsListenerContainerFactory (a factory that creates listener containers) whereas the XML is creating a listener container directly.

The factory is useful if you need to create lots of containers with similar properties.

For simple container configuration, when you are not using annotated listeners, it certainly might be simpler to use traditional XML, or @Bean definitions for the container.

For the second question, the default registrar is already populated with the container factory bean name when it is passed into the configureListeners method; you don't have to set it.

0
On

SimpleJmsListenerEndpoint always looks for named bean "jmsListenerContainerFactory". so even there is no explicitly setting:

registrar.setContainerFactoryBeanName("jmsListenerContainerFactory");

JmsListenerEndpoint still can find the JmsListenerContainerFactory if there exists bean "jmsListenerContainerFactory". Mean that in case you need to apply JmsListenerContainerFactory with different bean name, then setting on method registrar.setContainerFactoryBeanName("") doesn't effect at all.

Code below for the work and not working cases:

// config factory class
@Bean(name = "customJMSListenerContainerFactory")
public DefaultJmsListenerContainerFactory 
listenerQueueFactory() {
DefaultJmsListenerContainerFactory factory = new 
DefaultJmsListenerContainerFactory();
//more configs...
return factory;
}

// on consumer class 
@Configuration
@EnableJms
public class MyConsumer implements JmsListenerConfigurer {
@Override
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {

SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
registrar.registerEndpoint(endpoint);
// this setting will not work => Spring JMS bug 
registrar.setContainerFactoryBeanName("customJMSListenerContainerFactory");
// but this setting works
registrar.setContainerFactory(listenerQueueFactory());
 }
}

This is bug of spring jms.