2

I'm building a REST API application with Spring Boot 2.1.6. I want to use JMS messaging in my app with Active MQ package (org.apache.activemq). I have MyEventController class which receives all kinds of events through http requests. I then want to send the information about the events as a JMS message to a topic so that the message consumer will update the database with the information from the events.

The reason I want to use JMS here is to not hold the Spring thread which handle http request and have the consumer open a separate thread to do potentially a lot of time consuming updates to the database. However I'm wondering if JMSTemplate stays always one thread. Because if a new thread is opened for each http request then the solution is not so scalable.

This is my code for producer:

@RestController
public class MyEventController {
    @Autowired
    private DBHandler db;

    @Autowired
    private JmsTemplate jmsTemplate;

    @RequestMapping(method=GET, path=trackingEventPath)
    public ResponseEntity<Object> handleTrackingEvent(
            @RequestParam(name = Routes.pubId) String pubId,
            @RequestParam(name = Routes.event) String event) {

        jmsTemplate.convertAndSend("topic1", "info@example.com");
        return new ResponseEntity<>(null, new HttpHeaders(), HttpStatus.OK);
}

consumer:

@Component
public class JSMListener {
    @JmsListener(destination = "topic1", containerFactory = "topicListenerFactory")
    public void receiveTopicMessage(String event) {
        // do something...
    }
}
Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111
hitchhiker
  • 1,099
  • 5
  • 19
  • 44

1 Answers1

1

JmsTemplate has no concept of background threads or async sending. It's a class design for simplifying usage of java.jms.Session and embedding it with usual Spring concepts e.g. declarative transaction management with @Transactional.

In your example convertAndSend() will execute as part of the request processing thread. The method will block until the JMS broker responds to the application that the message was added to the destination queue or throw an exception if there was a problem e.g. queue was full.

Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111
  • 1
    However, for performance reasons you should use a `CachingConnectionFactory` with cached producers (default). (Unless you have some other pooling connection factory). Otherwise a new connection/producer is created and discarded for each send; this is very inefficient. – Gary Russell Jul 31 '19 at 21:05
  • What is the best practice if I want to send a JMS message in Spring? Is there a Spring/JMS API that allows to send messages in a separate thread? – hitchhiker Aug 01 '19 at 07:10