this is my first time with Spring JMS (and with JMS in general) and I have some doubts related the concept of the JmsTemplate callback.
I know that the JmsTemplate is a class provided from Spring to:
and that it is used for message production and synchronous message reception. It simplifies the use of JMS since it handles the creation and release of resources when sending or synchronously receiving messages.
Reading the Spring official documentation (here: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jms.html) I found:
Code that uses the JmsTemplate only needs to implement callback interfaces giving them a clearly defined high level contract. The MessageCreator callback interface creates a message given a Session provided by the calling code in JmsTemplate.
This is not clear for me. What exactly are these callback?
At the beginning I thought that a callback are a method provided from the JmsTemplate but reading here it seems something more similar to an interface that I have to implement. How it works?
I also found this example:
SENDING A POJO THROUGHT JMS (using the JmsTemplate):
public class JmsOrderManager implements OrderManager {
@Autowired JmsTemplate jmsTemplate;
@Autowired Destination orderQueue;
public void placeOrder(Order order) {
String stringMessage = "New order " + order.getNumber();
jmsTemplate.convertAndSend("messageQueue", stringMessage );
// use destination resolver and message converter
jmsTemplate.convertAndSend(orderQueue, order); // use message converter
jmsTemplate.convertAndSend(order); // use converter and default destination
}
}
I thought that the convertAndSend() method is a JmsTemplate callback but probably this assertion is not correct.
Can you explain me what exactly is a JmsTemplate callback?
The JmsTemplate class is used for message production and synchronous message reception. For asynchronous reception similar to Java EE's message-driven bean style, Spring provides a number of message listener containers that are used to create Message-Driven POJOs (MDPs). The package org. springframework.
JmsTemplate class handles the creation and releasing of resources when sending or synchronously receiving messages. Hence the class that uses this JmsTemplate only needs to implement callback interfaces as specified in the method definition.
Instances of the JmsTemplate class are thread-safe once configured. This is important because it means that you can configure a single instance of a JmsTemplate and then safely inject this shared reference into multiple collaborators.
An exception that is thrown by a JMS 1.1 API call is often the result of a lower level problem which is reported by another exception that is linked to this exception. Your application can obtain a linked exception by calling either the JMSException. getLinkedException() method or the Throwable. getCause() method.
The design principle common to Spring template classes is to provide helper methods to perform common operations and for more sophisticated usage, delegate the essence of the processing task to user implemented callback interfaces.
In JMS Connection will be obtained from a factory
=> From that connection session is created, a seesion is a unit of work, it also provides transaction
=> from session you create different types of JMS Message like TextMessage, ObjectMessage, MapMessage, BytesMessage and StreamMessage in following ways session.createTextMessage("hello queue world"); session.createObjectMessage(someSerializedObject) and so on
=> The same session is also responsible for creating instance of MessageProducer session.createProducer(destination) and MessageConsumer session.createConsumer(destination)
You have following convertAndSend possibilities (Overloaded methods):
jmsTemplate.convertAndSend(message)
jmsTemplate.convertAndSend(destination, message)
jmsTemplate.convertAndSend(message, postProcessor)
jmsTemplate.convertAndSend(destinationName, message)
jmsTemplate.convertAndSend(destination, message, postProcessor)
jmsTemplate.convertAndSend(destinationName, message, postProcessor)
What is happening? The basic use of callback like 3rd 5th and 6th signature is you can change the message after being converting the object to a JMS message through a configured MessageConverter. You are seeing an actual destination to be resolved by a DestinationResolver in case of 6th, you are not passing it, it will be resolved from JNDI, if it is registered there.
What does it mean?
jmsTemplate.send(this.queue, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("hello queue world");
}
});
Here in this example you are seeing with send() method of JMS template you are providing anonymous implemetation(callback) where the method gives you access to to Session Object and from that session you created customized session.createTextMessage("hello queue world") message.
Same way in convertAndSend(you can get access to postprocessors to modify)
public void ConvertSend() {
Map map = new HashMap();
map.put("Name", "Vimal");
map.put("Age", new Integer(45));
jmsTemplate.convertAndSend("jmsQueue", map, new MessagePostProcessor() {
public Message postProcessMessage(Message message) throws JMSException {
message.setIntProperty("ID", 9999);
message.setJMSCorrelationID("123-99999");
return message;
}
});
}
Message Object was created but you are modifying it(adding two more properties, in addition to name and age). The MessagePostProcessor interface gives you access to the message after it has been converted, but before it is sent.
In other words! setting of message properties, headers and body can't be encapsulated inside a converter class(SimpleMessageConverter), but the MessagePostProcessor Interface gives you access to the message after it has been converted, but before sent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With