Spring Integration中的不可变消息

时间:2018-01-09 08:22:29

标签: spring-integration

我想知道在Spring Integration中使消息不可变的原因是什么。

是否仅仅是因为多线程环境中的线程安全性?

性能?如果每次要在现有消息中添加内容时都必须创建新消息,那么您是否会受到性能损失?

通过引用传递时避免一系列错误? 只是在这里猜测。

1 个答案:

答案 0 :(得分:5)

最简单的解释方法来自原始Java Immutable Objects idea

  

不可变对象在并发应用程序中特别有用。由于它们不能改变状态,因此它们不会被线程干扰破坏或在不一致状态下被观察到。

由于我们在这里谈论消息,我们应该始终牢记Loose coupling principle生产者(调用者)和消费者(执行者)对彼此一无所知,他们只通过消息(事件,命令,包等)进行通信)。同时,相同的消息可能有几个消费者执行绝对不相关的业务逻辑。因此,支持活动对象的不可变状态,我们不会影响另一个进程。当我们单独执行消息时,这也可能是进程之间安全性的一部分。

Spring Integration实际上是纯Java,所以任何并发和安全限制也只是简单地应用在这里,你会惊讶地将消息分发给不同的独立进程,并看到另一个进程的修改。

Reference Manual中有一些信息:

  

因此,当Message实例发送给多个消费者时(例如通过发布订阅频道),如果其中一个消费者需要发送具有不同有效负载类型的回复,则需要创建一个新的Message。因此,其他消费者不会受到这些变化的影响。

如您所见,它适用于Message对象本身及其MessageHeaderspayload完全是您的责任,我在过去在多线程业务逻辑中向ArrayList有效负载添加和删除元素时遇到了一些问题。

无论如何,框架建议妥协:MutableMessageMutableMessageHeadersMutableMessageBuilder。您还可以在内部全局覆盖框架中使用的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();
}

集成流程中的所有消息都将可变并提供相同的idtimestamp标头。