The thing to remember is JmsTemplate is designed for use in EJBs using the EJB containers JMS pooling abstraction. So every method will typically create a connection, session, producer or consumer, do something, then close them all down again. The idea being that this will use the J2EE containers pooling mechanism to pool the JMS resources under the covers. Without using a pooled JMS provider from the EJB container this is the worst possible way of working with JMS; since typically each create/close of a connection, producer/consumer results in a request-response with the JMS broker.
You should only use JmsTemplate with a pooled JMS provider. In J2EE 1.4 or later that typically means a JCA based JMS ConnectionFactory. If you are in an EJB then make sure you use your J2EE containers ConnectionFactory, never a plain-old-connection factory. If you are not inside an EJB Then you should use our PooledConnectionFactory, then things will be nicely pooled. If you need to take part in XA transactions then look into our spring based JCA Container.
Another gotcha I've seen folks do is to create a MessageConsumer inside one of the SessionCallback methods then wonder why messages are not being received. After the SessionCallback is called, the session will be closed; which will close your consumers too . So if you want to create a MessageConsumer you should create a connection, session and consumer yourself.
Another problem I've seen is folks using the JmsTemplate.receive() method; as I've said above if you're not in an EJB using the J2EE containers ConnnectionFactory, a connection, session & consumer will be create and closed for each receive() method. This is all fine and well - if painfully slow unless you are using pooling - but be aware that this mechanism, without pooling, may well miss messages. If you are consuming on a topic which has messages sent with NON_PERSISTENT delivery mode then chances are you will miss messages, since each receive() call is a brand new consumer which will not receive any messages sent before the consumer existed. To receive messages efficiently you should use Spring's MessageListenerContainer.