This post demonstrates how to embed an ActiveMQ instance in Spring Boot and produce/consume messages with a simple example.
Spring Boot Application
You may still use the Spring Initialzr which is fine but we need to update the generated pom.xml to include additional dependencies.
1 2 3 4 5 6 7 8 9 10 11 | <!-- START: These are the additional dependencies needed --> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-kahadb-store</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> </dependency> <!-- END: These are the additional dependencies needed --> |
Our @Configuration class
We have two parts here – the embedded JMS server and client-stuff sections. @EnableJMS f is just an annotation that allows us to use @JmsListener (see MessageReceiver class).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | package com.turreta.springboot.embedded.jms; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.broker.BrokerService; import org.apache.activemq.broker.TransportConnector; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jms.annotation.EnableJms; import org.springframework.jms.core.JmsTemplate; import java.net.URI; import java.util.Arrays; @Configuration @EnableJms public class MyConfig { public static final String DEFAULT_BROKER_URL = "tcp://localhost:61616"; public static final String COMMENT_QUEUE = "comment-queue"; /** * This represents a JMS server. In this case, this is an embedded JMS server. * In production, you always connect to external JMS servers. * * @return * @throws Exception */ @Bean public BrokerService createBrokerService() throws Exception { BrokerService broker = new BrokerService(); TransportConnector connector = new TransportConnector(); connector.setUri(new URI("tcp://localhost:61616")); broker.addConnector(connector); return broker; } /** * Part of JMS client * * @return */ @Bean public ActiveMQConnectionFactory connectionFactory(){ ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(); connectionFactory.setBrokerURL(DEFAULT_BROKER_URL); connectionFactory.setTrustedPackages(Arrays.asList("com.turreta")); return connectionFactory; } /** * Part of JMS client * * @return */ @Bean public JmsTemplate jmsTemplate(){ JmsTemplate template = new JmsTemplate(); template.setConnectionFactory(connectionFactory()); template.setDefaultDestinationName(COMMENT_QUEUE); return template; } } |
Our Main class
In this class, we send a message to the JMS queue.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | package com.turreta.springboot.embedded.jms; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import java.util.concurrent.TimeUnit; @SpringBootApplication public class ComTurretaSpringbootEmbeddedJmsApplication { public static void main(String[] args) throws Exception { ApplicationContext ctx = SpringApplication.run(ComTurretaSpringbootEmbeddedJmsApplication.class, args); MessageSender msgSender = (MessageSender)ctx.getBean("messageSender"); // Send message to a JMS queue msgSender.sendMessage("This is the first msg \n"); // Give it some time to process TimeUnit.MINUTES.sleep(2); } } |
Sample Output
Download the Codes
https://github.com/Turreta/Spring-Boot-Embedded-JMS
i have requirement like when some event happens in one of the web servers, it will send message to the remaining web servers that are running behind the load balancer, how can i achieve with this? thanks in advance
Apologies from the late response. Did you mean web servers or web applications? If web servers, then I’d imagine any changes to implement your requirements may be done through some configurations.
If web applications, then we are generally talking about code changes.
in production i have load balancer and multiple web applications running on the multiple tomcats, if some event happens in the one of the web application that is running on the web server, then it should be notified to the other same web application running on the different web server, if you an idea how we can achieve this with spring embedded mq , please let me know.
Thanks.
From the top of my head, I think embedded MQ might not work as it is only available to one of the web applications. A remote MQ may be a solution as all web applications can push to and receive events from a common queue or topic. I’d imagine you won’t need any load-balancing for events.