0

I am using org.springframework.jms.core.JmsTemplate; in my project to send messages to SQS queues.

I autowired JmsTemplate in a @Service

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;

@Service
public class AmazonSQSPublisherImpl implements AmazonSQSPublisher {
    @Autowired
    private JmsTemplate jmsTemplate;
    @Override
    public boolean sendMessageToFifo(String queueName, String message,
                                     String messageGroupId, String messageDedupeId, long delayTime) throws EventBrokerException {
        jmsTemplate.setDeliveryDelay(delayTime);
        jmsTemplate.send(queueName, session -> {/* somemessage here*/});
    }

    @Override
    public boolean sendMessage(String queueName, String message) throws EventBrokerException {
        jmsTemplate.convertAndSend(queueName, message);
    }
}

Here I use setDeliveryDelay inside the jmsTemplate. So my question is: As I known, bean is singleton by default. if I used the setter of the jmsTemplate bean, should I reset it? In my example, should I add this at the end of method sendMessageToFifo:

jmsTemplate.setDeliveryDelay(0);

If I don't add this, when I call sendMessage rather than sendMessageToFifo, the delivery delay will not be zero, right?

Also, I want to ask if any best practices for call setter of autowired bean??

Petar Bivolarski
  • 1,599
  • 10
  • 19
Hongli Bu
  • 461
  • 12
  • 37

2 Answers2

4

All beans are singleton by default, so yes one way is to reset it.

But imho thats an ugly solution.

What you should do is to define a dedicated JmsTemplate @Bean that you custom configure and then autowire where you need.

If you need another JmsTemplate for any other place you define a second @Bean and you separate these two by using @Qualifiers.

Toerktumlare
  • 12,548
  • 3
  • 35
  • 54
2

All beans are singleton by default, so I think that you should reset it as you suggest.

As stated in Spring`s documentation:

The singleton scope is the default scope in Spring. (...) When a bean is a singleton, only one shared instance of the bean will be managed, and all requests for beans with an id or ids matching that bean definition will result in that one specific bean instance being returned by the Spring container.

This means that the next time jmsTemplate is called, it will have its previously added state-data.

There are other bean scopes, which you can view in the source above.

In terms of using field injection via the @AutoWired annotation, it is generally not considered a good practice due to various issues listed here (prefer constructor or setter injection instead).

Petar Bivolarski
  • 1,599
  • 10
  • 19