The JmsTemplate is a helper class that simplifies synchronous JMS access code which resides in org.springframework.jms.core package. It has two versions namely JmsTemplate and JmsTemplate102 supporting JMS 1.1 and JMS 1.0.2 respectively. JmsTemplate102 is deprecated as of Spring 3.0; in favor of the JMS 1.1 based JmsTemplate.
The various functions which this helper class provides to a developer can be summarized as below:
- Manages resources transparently to the developer (Good level of abstraction).
- Reduces boilerplate code involved in traditional messaging-based applications.
- Handles exception in simple and consistent manner.
- Converts checked exception into unchecked runtime exceptions for any JMS provider in a consistent manner.
- Provides with convenience methods and callbacks to handle various messaging challenges.
To achieve various functionalities JmsTemplate use delegation model. It delegates to appropriate collaborators to do some specific works so as to relieve itself from such nitty-gritty’s. The two collaborators commonly employed are:
MessageConverter is a strategy interface that specifies a converter between Java objects and JMS messages. The SimpleMessageConverter is the default implementation which converts between the ‘standard’ message payloads and JMS Message types. The simple message converter is able to handle TextMessages, BytesMessages, MapMessages, and ObjectMessages. The conversions done by this converter are:
- String to TextMessage
- Serializable to ObjectMessage
- Map to MapMessage
- byte to BytesMessage
If your application requires a different message conversion strategy, you can always have your own converters plugged on. Implement the MessageConverter interface and implement the two methods as shown below according to your conversion strategy:
- Object fromMessage(Message message)
- Message toMessage(Object object, Session session)
After implementing the new converter you can use the Spring DI to inject this converter to the JmsTemplate.
DestinationResolver is a strategy interface for resolving JMS destinations. It is used by JmsTemplate for resolving destination names from simple Strings to actual Destination implementation instances. The default DestinationResolver implementation used by JmsTemplate instances is the DynamicDestinationResolver class. Other implementations of this interface are BeanFactoryDestinationResolver and JndiDestinationReolver. For advanced scenarios using JndiDestinationResolver is more apt.
The interface DestinationResolver has only one method, Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain).
Spring’s Message Listener Container
In Spring receiving messages asynchronously is achieved by using Message driven POJO’s (MDP). MDP’s are created within the context of a message listener container. The message listener container is analogous to JmsTemplate and deals with asynchronous messaging. The message listeners in Spring can be configured by three methods as summarized below:
- Your POJO implementing JMS’s javax.jms.MessageListener interface. Similar to MDB’s it contains a method namely onMessage(Message message) which needs to be implemented.
- Your POJO implementing Spring’s org.springframework.jms.listener.SessionAwareMessageListener interface. It also contains only single method namely onMessage(Message message, Session session) which needs o be implemented.
- Last but not the least is to wrap your POJO using Spring’s org.springframework.jms.listener.adapter.MessageListenerAdapter class.
Note: The sending of response messages is only available when using the SessionAwareMessageListener entry point. Usage of standard JMS MessageListener does not support the generation of response messages.
Configuring JMS Resources with Spring
Spring Framework inline with its core principles abstracts away the complexities to create a message oriented application. It does this by decoupling your application code from the underlying infrastructure. By doing this your application enjoys one of the very important feature of modern day application; deployment flexibility. For message-oriented nature of your application you definitely need JMS resources. With Spring, your application can use standalone JMS provider or can use the application server managed JMS resources with ease.
Two very important JMS resource required by the JMS provider to function in the overall ecosystem of Spring JMS is ConnectionFactory and Destinations. ConnectionFactory is used by the JMS client to create connections to the JMS provider and Destinations are used by the JMS client to represent the target and source of messages.
Configuring a ConnectionFactory
A connection factory is an object that a JMS client uses to create a connection with a JMS provider. Connection factories in real enterprise application are administered objects which are stored in a JNDI namespace, which is a defined location within the naming and directory service. If a JMS client has to create connections to a different messaging provider, you must create a new connection factory and specify the messaging provider.
As discussed earlier, there are two messaging types: the point-to-point messaging and publish/subscribe messaging type. You have a provision to create a connection factory to create connections specifically for point-to-point messaging (using the QueueConnectionFactory interface) or specifically for publish/subscribe messaging (using the TopicConnectionFactory interface). However if you want to perform both point-to-point and publish/subscribe work in the same transaction context, you can create a domain-independent connection factory.
ConnectionFactory can be declared as a bean in the Spring configuration file as standalone or retrieved from JNDI as shown in Listing 18-6 and Listing 18-7 respectively.
Listing 18-6. ConnectionFactory configured as standalone
<bean id=”connectionFactory” class=”org.apache.activemq.ActiveMQConnectionFactory”>
<property name=”brokerURL” value=”tcp://localhost:99999”/>
Listing 18-7. ConnectionFactory configured as retrieved from JNDI
<jee:jndi-lookup id=”connectionFactory” jndi-name=”jms/ConnectionFactory”/>
Page Visitors: 14545