2
votes

The spring documentation says:

Destinations, as ConnectionFactory instances, are JMS administered objects that you can store and retrieved in JNDI. When configuring a Spring application context, you can use the JNDI JndiObjectFactoryBean factory class or to perform dependency injection on your object’s references to JMS destinations.

However, this strategy is often cumbersome if there are a large number of destinations in the application or if there are advanced destination management features unique to the JMS provider.

The question is:

How to proceed when I have a large number of destinations in my application?

Using the strategy mentioned above I have to define:

  • JndiTemplate
  • JndiDestinationResolver
  • JndiObjectFactoryBean
  • CachingConnectionFactory
  • JmsTemplate

For EACH destination.

So If I have 20 queues, I'll have to define 100 such beans...

2
You can lazily resolve the destinations, you only need a single JmsTemplate and ConnectionFactory (assuming they all are using the same JMS provider/instance). Everything else can be lazily looked up using the send(destination, message) methods on the JmsTemplate.M. Deinum

2 Answers

2
votes

The comment in the Spring documentation makes a note on 'using JNDI for destination endpoints' versus 'not using JNDI for destination endpoints'. So in your case - are your destinations stored in JNDI ? If you don't have to use that, forget about it. Only load your ConnectionFactory (one object) from JNDI or simply create it from scratch.

And then you don't have to assign one Spring bean to each destination. You could have just one Java 'consumer bean' which then uses JmsTemplate. I guess your connection factory is the same, so that's only one new JmsTemplate(connectionFactory). Then do createSession/createConsumer, etc. as needed.

2
votes

You can just use a single JmsTemplate, CachingConnectionFactory and JndiDestinationResolver...

The whole point of using a DestinationResolver is to lazily resolve the destinations for you. Use the specific send or [convertAndSend][5]. ThedestininationNamewill be passed on to theDestinationResolver` to get the destination.

The only drawback is that you need to use the jndi-name as the destinationName.


@Bean
public JndiDestinationResolver jndiDestinationResolver() {
  return new JndiDestinationResolver();
}

@Bean
public JmsTemplate jmsTemplate() {
  JmsTemplate jmsTemplate = new JmsTemplate();
  jmsTemplate.setDestinationResolver(jndiDestinationResolver());
  jmsTemplate.setConnectionFactory(connectionFactory());
  return jmsTemplate;
}

With this you can use the following to dynamically resolve the destination from JNDI.


jmsTemplate.send("jms/queue1", "This is a message");
jmsTemplate.send("jms/queue3", "This is another message");