我是否应该在 Spring 中手动重置 Autowired Bean 的状态数据(因为它是 Singleton)?
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 -> {/* somemessage here*/});
}
@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 有什么最佳实践吗??
默认情况下所有的bean都是单例的,所以我认为你应该按照你的建议重新设置它。
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.
这意味着下次调用 jmsTemplate
时,它将具有之前添加的状态数据。
还有其他的bean作用域,你可以在上面的源码中查看。
就通过 @AutoWired
注释使用字段注入而言,由于列出的各种问题 通常不被认为是一种好的做法(更喜欢构造函数或 setter 注入) .
默认情况下所有 bean 都是单例的,所以是的,一种方法是重置它。
但是恕我直言,这是一个丑陋的解决方案。
你应该做的是定义一个你自定义配置的专用 JmsTemplate
@Bean
然后 autowire
在你需要的地方。
如果您需要另一个 JmsTemplate
用于任何其他地方,您可以定义第二个 @Bean
并使用 @Qualifiers
.
将这两个分开
我在我的项目中使用 org.springframework.jms.core.JmsTemplate; 将消息发送到 SQS 队列。
我在 @Service
中自动装配了 JmsTemplateimport 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);
}
}
这里我在jmsTemplate中使用了setDeliveryDelay。所以我的问题是: 正如我所知,默认情况下 bean 是单例的。如果我使用了 jmsTemplate bean 的 setter,我应该重置它吗?在我的示例中,我应该在方法 sendMessageToFifo:
的末尾添加它吗jmsTemplate.setDeliveryDelay(0);
如果我不加这个,当我调用sendMessage而不是sendMessageToFifo时,传递延迟不会为零,对吧?
此外,我想问一下自动装配 bean 的调用 setter 有什么最佳实践吗??
默认情况下所有的bean都是单例的,所以我认为你应该按照你的建议重新设置它。
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.
这意味着下次调用 jmsTemplate
时,它将具有之前添加的状态数据。
还有其他的bean作用域,你可以在上面的源码中查看。
就通过 @AutoWired
注释使用字段注入而言,由于列出的各种问题
默认情况下所有 bean 都是单例的,所以是的,一种方法是重置它。
但是恕我直言,这是一个丑陋的解决方案。
你应该做的是定义一个你自定义配置的专用 JmsTemplate
@Bean
然后 autowire
在你需要的地方。
如果您需要另一个 JmsTemplate
用于任何其他地方,您可以定义第二个 @Bean
并使用 @Qualifiers
.