For sending messages we will be using the JmsTemplate which requires a reference to a ConnectionFactory. The template provides convenience methods which handle the creation and release of resources when sending or synchronously receiving messages.
In the below Sender class, the JmsTemplate is auto-wired as the actual creation of the Bean will be done in a separate SenderConfig class.
In this tutorial we will use the convertAndSend() method which sends the given object to the helloworld.q destination, converting the object to a JMS message.
The type of JMS message depends on the type of the object being passed. In the case of a String, a JMS TextMessage will be created.
The creation of the JmsTemplate and Sender is handled in the SenderConfig class. This class is annotated with @Configuration which indicates that the class can be used by the Spring IoC container as a source of bean definitions.
In order to be able to use the Spring JMS template, we need to provide a reference to a ConnectionFactory which is used to create connections with the JMS provider. In addition, it encapsulates various configuration parameters, many of which are vendor specific.
In the case of ActiveMQ, we use the ActiveMQConnectionFactory.
On the ActiveMQConnectionFactory we set the broker URL which is fetched from the application.yml properties file using the @Value annotation.
The JmsTemplate was originally designed to be used in combination with a J2EE container where the container would provide the necessary pooling of the JMS resources.
As we are running this example on Spring Boot, we will wrap ActiveMQConnectionFactory using Spring’s CachingConnectionFactory in order to still have the benefit of caching of sessions, connections, and producers as well as automatic connection recovery.
6. Create a Spring JMS Message Consumer
Like with any messaging-based application, you need to create a receiver that will handle the messages that have been sent. The below Receiver is nothing more than a simple POJO that defines a method for receiving messages. In this guide we named the method receive(), but you can name it anything you like.
The @JmsListener annotation creates a message listener container behind the scenes for each annotated method, using a JmsListenerContainerFactory. By default, a bean with name jmsListenerContainerFactory is expected that we will set up in the next section.
Using the destination element, we specify the destination for this listener. In the below example we set the destination to helloworld.q.
For testing convenience, we added a CountDownLatch. This allows the POJO to signal that a message is received. This is something you are not likely to implement in a production application.
The creation and configuration of the different Spring Beans needed for the Receiver POJO are grouped in the ReceiverConfig class.
Note that we need to add the @EnableJms annotation to enable support for the @JmsListener annotation that was used on the Receiver.
The jmsListenerContainerFactory() is expected by the @JmsListener annotation from the Receiver.
Spring Boot will automatically start an embedded broker if following conditions are met:
ActiveMQ is on the classpath.
No broker URL is specified through spring.activemq.broker-url.
Let’s use the embedded broker for testing. We add a dedicated application.yml properties file under src/test/resources. Inside we specify the VM URI as broker connection URL.
Next, we create a basic SpringJmsApplicationTest class to verify that we are able to send and receive a message to and from ActiveMQ.
It contains a testReceive() unit test case that uses the Sender to send a message to the 'helloworld.q' queue on the ActiveMQ message broker. We then use the CountDownLatch from the Receiver to verify that a message was received.
In order to execute the above test, open a command prompt in the project root directory and run following Maven command:
Maven will download the dependencies, compile the code and run the unit test case. The result should be a successful build as shown below:
Above test case can also be executed after you install Apache ActiveMQ on your local system. Simply change the 'activemq:broker-url' property to point to 'tcp://localhost:61616' in case the broker is running on the default URL.
If you would like to run the above code sample you can get the full source code here.
This concludes our example in which we used Spring JMS and Spring Boot in order to connect to ActiveMQ.
If you found this sample useful or have a question you would like to ask.