Skip to content

Messaging with JMS :: Learn how to publish and subscribe to messages using a JMS broker.

Notifications You must be signed in to change notification settings

alek-sys/gs-messaging-jms

 
 

Repository files navigation

tags projects
messaging
jms
spring-framework

This guide walks you through the process of publishing and subscribing to messages using a JMS broker.

What you’ll build

You’ll build an application that uses Spring’s JmsTemplate to post a single message and subscribes to it with a @JmsListener annotated method of a managed bean.

Create a message receiver

Spring provides the means to publish messages to any POJO.

In this guide, you will look at how to send a message out over a JMS message broker. To start things off, let’s create a very simply POJO that embodies the details of an email message. Pay note, we aren’t sending an email message. We’re simply sending the details from one place to another about WHAT to send in a message.

src/main/java/hello/Email.java

link:complete/src/main/java/hello/Email.java[role=include]

This POJO is quite simple, containing two fields, to and body, along with the presumed set of getters and setters.

From here, you can define a message receiver:

src/main/java/hello/Receiver.java

link:complete/src/main/java/hello/Receiver.java[role=include]

Receiver is also known as a message driven POJO. As you can see in the code above, there is no need to implement any particular interface or for the method to have any particular name. Besides, the method may have a very flexible signature. Note in particular that this class has no import on the JMS API.

The JmsListener annotation defines the name of the Destination that this method should listen to and the reference to the JmsListenerContainerFactory to use to create the underlying message listener container. Strictly speaking that last attribute is not necessary unless you need to customize the way the container is built as Spring Boot registers a default factory if necessary.

The reference documentation covers this in more detail.

Send and receive JMS messages with Spring

Next, wire up a sender and a receiver.

src/main/java/hello/Application.java

link:complete/src/main/java/hello/Application.java[role=include]

@EnableJms triggers the discovery of methods annotated with @JmsListener, creating the message listener container under the covers.

For clarity, we have also defined a myFactory bean that is referenced in the JmsListener annotation of the receiver. Because we use the DefaultJmsListenerContainerFactoryConfigurer infrastructure provided by Spring Boot, that JmsMessageListenerContainer will be identical to the one that boot creates by default.

The default MessageConverter is able to convert only basic types (such as String, Map, Serializable) and our Email is not Serializable on purpose. We want to use Jackson and serialize the content to json in text format (i.e. as a TextMessage). Spring Boot will detect the presence of a MessageConverter and will associate it to both the default JmsTemplate and any JmsListenerContainerFactory created by DefaultJmsListenerContainerFactoryConfigurer.

JmsTemplate makes it very simple to send messages to a JMS destination. In the main runner method, after starting things up, you can just use jmsTemplate to send an Email POJO. Because our custom MessageConverter has been automatically associated to it, a json document will be generated in a TextMessage only.

Two beans that you don’t see defined are JmsTemplate and ConnectionFactory. These are created automatically by Spring Boot. In this case, the ActiveMQ broker runs embedded.

By default, Spring Boot creates a JmsTemplate configured to transmit to queues by having pubSubDomain set to false. The JmsMessageListenerContainer is also configured the same. To override, set spring.jms.isPubSubDomain=true via Boot’s property settings (either inside application.properties or by environment variable). Then make sure the receiving container has the same setting.

Note
Spring’s JmsTemplate can receive messages directly through its receive method, but that only works synchronously, meaning it will block. That’s why we recommend that you use a listener container such as DefaultMessageListenerContainer with a cache-based connection factory, so you can consume messages asynchronously and with maximum connection efficiency.

When it runs, buried amidst all the logging, you should see these messages:

Sending an email message.
Received <Email{to=info@example.com, body=Hello}>

Summary

Congratulations! You’ve just developed a publisher and consumer of JMS-based messages.

About

Messaging with JMS :: Learn how to publish and subscribe to messages using a JMS broker.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Shell 52.3%
  • Batchfile 36.1%
  • Java 11.6%