我想知道在Spring Integration中使消息不可变的原因是什么。
是否仅仅是因为多线程环境中的线程安全性?
性能?如果每次要在现有消息中添加内容时都必须创建新消息,那么您是否会受到性能损失?
通过引用传递时避免一系列错误? 只是在这里猜测。
答案 0 :(得分:5)
最简单的解释方法来自原始Java Immutable Objects idea:
不可变对象在并发应用程序中特别有用。由于它们不能改变状态,因此它们不会被线程干扰破坏或在不一致状态下被观察到。
由于我们在这里谈论消息,我们应该始终牢记Loose coupling principle生产者(调用者)和消费者(执行者)对彼此一无所知,他们只通过消息(事件,命令,包等)进行通信)。同时,相同的消息可能有几个消费者执行绝对不相关的业务逻辑。因此,支持活动对象的不可变状态,我们不会影响另一个进程。当我们单独执行消息时,这也可能是进程之间安全性的一部分。
Spring Integration实际上是纯Java,所以任何并发和安全限制也只是简单地应用在这里,你会惊讶地将消息分发给不同的独立进程,并看到另一个进程的修改。
Reference Manual中有一些信息:
因此,当
Message
实例发送给多个消费者时(例如通过发布订阅频道),如果其中一个消费者需要发送具有不同有效负载类型的回复,则需要创建一个新的Message
。因此,其他消费者不会受到这些变化的影响。
如您所见,它适用于Message
对象本身及其MessageHeaders
。 payload
完全是您的责任,我在过去在多线程业务逻辑中向ArrayList
有效负载添加和删除元素时遇到了一些问题。
无论如何,框架建议妥协:MutableMessage
,MutableMessageHeaders
和MutableMessageBuilder
。您还可以在内部全局覆盖框架中使用的MessageBuilder
MutableMessageBuilderFactory
。为此,您只需要使用bean名称IntegrationUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME
注册这样的bean:
@Bean(name = IntegrationUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME)
public static MessageBuilderFactory mutableMessageBuilderFactory() {
return new MutableMessageBuilderFactory();
}
集成流程中的所有消息都将可变并提供相同的id
和timestamp
标头。