Setting Up the Message Broker
Java Message Service (JMS) defines a standard API for creating, sending, and receiving messages. Apache ActiveMQ is a robust, open-source message broker that implements this specification, serving as a powerful tool for asynchronous communication.
To begin, download the ActiveMQ distribution from the official Apache website and extract the archive. Start the broker by navigating to the bin directory and executing the startup script.
Configuring the Connection Factory
To interact with the broker, the application requires a ConnectionFactory. This component manages the connection pool and facilitates communication with the ActiveMQ server running on tcp://localhost:61616.
Java Configuration
private static final String BROKER_URL = "tcp://localhost:61616";
@Bean
public ConnectionFactory jmsConnectionFactory() {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
factory.setBrokerURL(BROKER_URL);
return factory;
}
XML Configuration
<bean id="connectionFactory"
class="org.apache.activemq.spring.ActiveMQConnectionFactory"
p:brokerURL="tcp://localhost:61616"/>
Defining Message Destinations
Destinations represent the specific targets where messages are delivered. JMS supports two primary destination types: Queues (Point-to-Point) and Topics (Publish-Subscribe).
Queue Configuration
@Bean
public Queue orderQueue() {
return new ActiveMQQueue("app.orders.queue");
}
Topic Configuration
@Bean
public Topic notificationTopic() {
return new ActiveMQTopic("app.notifications.topic");
}
Sending Messages with Native JMS API
Before utilizing Spring's abstractions, it is useful to understand how the standard JMS API operates. The following example demonstrates creating a connection, session, and producer manually.
public void dispatchRawMessage() throws JMSException {
Connection jmsConnection = jmsConnectionFactory.createConnection();
Session jmsSession = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = new ActiveMQQueue("app.orders.queue");
MessageProducer producer = jmsSession.createProducer(destination);
TextMessage textMessage = jmsSession.createTextMessage();
textMessage.setText("Native JMS Payload");
producer.send(textMessage);
producer.close();
jmsSession.close();
jmsConnection.close();
}
public void consumeRawMessage() throws JMSException {
Connection jmsConnection = jmsConnectionFactory.createConnection();
jmsConnection.start();
Session jmsSession = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = new ActiveMQQueue("app.orders.queue");
MessageConsumer consumer = jmsSession.createConsumer(destination);
Message message = consumer.receive();
if (message instanceof TextMessage) {
System.out.println(((TextMessage) message).getText());
}
consumer.close();
jmsSession.close();
jmsConnection.close();
}
Configuring JmsTemplate
Spring simplifies JMS operations by providing the JmsTemplate class. It handles resource creation and cleanup, reducing boilerplate code. Below is the configuration for the template bean.
Java Configuration
@Bean
public JmsTemplate jmsTemplate(ConnectionFactory factory, Queue defaultDestination) {
JmsTemplate template = new JmsTemplate(factory);
template.setDefaultDestination(defaultDestination);
return template;
}
XML Configuration
<bean id="jmsTemplate"
class="org.springframework.jms.core.JmsTemplate"
c:_-ref="connectionFactory"
p:defaultDestination-ref="orderQueue"/>
Sending Messages with JmsTemplate
Using JmsTemplate, you can send messages using a MessageCreator callback. This approach abstracts the session management.
public void sendMessageUsingTemplate() {
jmsTemplate.send(session -> {
TextMessage message = session.createTextMessage();
message.setText("Spring JMS Payload");
return message;
});
}
public void receiveMessageUsingTemplate() throws JMSException {
TextMessage message = (TextMessage) jmsTemplate.receive();
System.out.println("Consumed: " + message.getText());
}
Using Message Converters
To further simplify development, Spring allows you to send and receive plain Java objects using a MessageConverter. The convertAndSend method automatically handles the object-to-message transformation.
public void sendConvertedMessage() {
jmsTemplate.convertAndSend("Automatic Conversion");
}
public void receiveConvertedMessage() {
String payload = (String) jmsTemplate.receiveAndConvert();
System.out.println("Converted Payload: " + payload);
}