英文:
Should I manually reset state-data of Autowired Bean in Spring (since it is Singleton)?
问题
我在项目中使用了**org.springframework.jms.core.JmsTemplate;**来向SQS队列发送消息。
我在一个@Service中自动装配了JmsTemplate
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 -> {/* 这里是一些消息内容*/});
}
@Override
public boolean sendMessage(String queueName, String message) throws EventBrokerException {
jmsTemplate.convertAndSend(queueName, message);
}
}
这里我在jmsTemplate内部使用了setDeliveryDelay方法。所以我的问题是:
据我所知,默认情况下bean是单例的。如果我使用了jmsTemplate bean的setter,我是否应该重新设置它?在我的示例中,我是否应该在sendMessageToFifo方法的末尾添加这行代码:
jmsTemplate.setDeliveryDelay(0);
如果我不添加这行代码,当我调用sendMessage而不是sendMessageToFifo时,投递延迟是否不会为零,对吗?
另外,我想问一下关于调用自动装配的bean的setter是否有什么最佳实践?
英文:
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??
答案1
得分: 4
所有的bean默认都是单例的,所以是的,一种方法是将其重置。
但在我看来,那是一个不好的解决方案。
你应该做的是定义一个专门的 JmsTemplate
@Bean
,在其中进行自定义配置,然后在需要的地方进行 autowire
。
如果你在其他任何地方需要另一个 JmsTemplate
,你可以定义第二个 @Bean
,并通过使用 @Qualifiers
来区分这两者。
英文:
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
.
答案2
得分: 2
所有的 bean 默认都是单例的,所以我认为你应该按照你的建议进行重置。
正如在 Spring 的文档 中所述:
> 单例作用域是 Spring 中的默认作用域。(...)
> 当一个 bean 是单例时,容器将只管理一个共享的 bean 实例,对于与该 bean 定义的 id 匹配的所有 bean 请求将导致 Spring 容器返回那个特定的 bean 实例。
这意味着下一次调用 jmsTemplate
时,它将具有先前添加的状态数据。
还有其他的 bean 作用域,你可以在上面的源代码中查看。
关于使用 @AutoWired
注解进行字段注入,通常不被认为是一种好的做法,因为存在各种问题,详见这里(最好使用构造函数或 setter 注入)。
英文:
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).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论