Spring Integration 中的不可变消息 [英] Immutable message in Spring Integration

查看:30
本文介绍了Spring Integration 中的不可变消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I was wondering what is the reasoning behind making messages immutable in Spring Integration.

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

Is it only because of thread-safety in multi threaded evnironments?

性能?当您每次想要向现有消息添加内容时都必须创建新消息时,您不会受到性能惩罚吗?

Performance? Don't you get a performance penalization when you have to create a new message each time you want to add something to an existing message?

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

Avoiding a range of bugs when passing by reference? Just guessing here.

推荐答案

最简单的解释方式来自于原文 Java 不可变对象的想法:

The simplest way to explain this comes from the original Java Immutable Objects idea:

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

Immutable objects are particularly useful in concurrent applications. Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state.

既然我们在这里谈论消息传递,我们应该始终牢记松耦合原则,其中生产者(调用者)和消费者(执行者)对彼此一无所知,他们仅通过消息(事件、命令、包等)进行通信.同时同一条消息可能有多个消费者执行完全不相关的业务逻辑.因此,支持活动对象的不可变状态,我们不会影响另一个进程.当我们单独执行消息时,这也可能是进程之间安全性的一部分.

Since we talk here about Messaging we should always keep in mind the Loose coupling principle where the producer (caller) and consumer (executor) know nothing about each other and they communicate only via messages (events, commands, packages etc.). At the same time the same message may have several consumers to perform absolutely not related business logics. So, supporting immutable state for the active object we don't impact one process from another. That's might be also as a part of the security between processes when we execute a message in isolation.

Spring 集成是真正的纯 Java,因此任何并发性和安全性限制也只是简单地应用在这里,您会惊讶地将消息分发到不同的独立进程,并在另一个进程中看到一个进程的修改.

The Spring Integration is really pure Java, so any concurrency and security restrictions just simply applied here as well and you would be surprised distributing a message to different independent processes and see modifications from one process in the other.

参考手册:

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

Therefore, when a Message instance is sent to multiple consumers (e.g. through a Publish Subscribe Channel), if one of those consumers needs to send a reply with a different payload type, it will need to create a new Message. As a result, the other consumers are not affected by those changes.

如您所见,它应用于 Message 对象本身及其 MessageHeaders.payload 完全由您负责,我过去在多线程业务逻辑中向 ArrayList 负载添加和删除元素时确实遇到了一些问题.

As you see it is applied for Message object per se and its MessageHeaders. The payload is fully your responsibility and I really had in past some problems adding and removing elements to the ArrayList payload in multi-threaded business logic.

无论如何,框架提出了一个折衷方案:MutableMessageMutableMessageHeadersMutableMessageBuilder.您还可以将框架内部使用的 MessageBuilder 全局覆盖为 MutableMessageBuilderFactory.为此,您只需要使用 bean 名称 IntegrationUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME 注册这样一个 bean:

Anyway the Framework suggest a compromise: MutableMessage, MutableMessageHeaders and MutableMessageBuilder. You also can globally override the MessageBuilder used in the Framework internally to the MutableMessageBuilderFactory. For this purpose you just need to register such a bean with the bean name IntegrationUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME:

@Bean(name = IntegrationUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME)
public static MessageBuilderFactory mutableMessageBuilderFactory() {
    return new MutableMessageBuilderFactory();
}

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

And all messages in your integration flows will be mutable and supply the same id and timestamp headers.

这篇关于Spring Integration 中的不可变消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆