JMS(Java Message Service) is a API provided by java to create, send and read messages. It provide both point-to-point and publish-subscribe messaging models. In this blog we will talk about JMS implementation using Spring Boot.
To create and manage message queue, we will use Apache Active MQ which enables applications to exchange messages asynchronously.
Maven dependencies required are:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-broker</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> </dependencies>
Now lets create a message receiver that picks the message from the queue.
import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; @Component public class Receiver { @JmsListener(destination = "msgQueue") public void receiveMessage(Message message) { System.out.println("Message Received " + message ); } }
Here, @JmsListener is used to mark Receiver class to be the target of JMS Message Listener of provided destination ("msgQueue")
Here, Message class is a DTO.
import java.io.Serializable; public class Message implements Serializable { private Long id; private String msg; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getMsg() { return content; } public void setMsg(String msg) { this.msg = msg; } public String toString() { return "Message [id=" + id + ", msg=" + msg"]"; } }
Now, to create a sender, i am creating a rest API
import org.springframework.jms.core.JmsTemplate; @RestController @RequestMapping("/messageExample") public class MessageSender{ @Autowired private JmsTemplate jmsTemplate; @PostMapping("/send") public void send(@RequestBody Message message){ System.out.println("Sending message..."); jmsTemplate.convertAndSend("msgQueue", message); } }
here, JmsTemplate is used, it is a helper class that helps to send or receive messages through JMS. It's convertAndSend() function converts object into message and sends it to the provided destination.
In the final step, we add @EnableJms and create JmsListenerContainerFactory in main method
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.jms.annotation.EnableJms; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; import org.springframework.jms.config.JmsListenerContainerFactory; import org.springframework.jms.support.converter.MappingJackson2MessageConverter; import org.springframework.jms.support.converter.MessageConverter; import org.springframework.jms.support.converter.MessageType; @SpringBootApplication @EnableJms public class JMSDemo { @Bean public JmsListenerContainerFactory<?> myFactory( ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); configurer.configure(factory, connectionFactory); return factory; } @Bean public MessageConverter JmsMessageConverter() { MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); converter.setTargetType(MessageType.TEXT); converter.setTypeIdPropertyName("_type"); return converter; } }
JmsListenerContainerFactory is responsible to create listener container. DefaultJmsListenerContainerFactory contains necessary configurations that are supported by the MessageListenerContainer.