Immutable Message in Spring Integration

I was wondering what is the reason that posts don't change in Spring integration.

Is it just because of thread safety in multi-threaded versions?

Performance? Aren't you getting a performance penalty when you need to create a new message every time you want to add something to an existing message?

Avoid a series of errors when passing by reference? Just guess here.

+5
source share
1 answer

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

Continuous objects are especially useful in parallel applications. Since they cannot change state, they cannot be damaged by stream interference or are observed in an inconsistent state.

Since we are talking about Messaging here, we should always keep in mind the principle of free communication , where the producer (caller) and consumer (performer) do not know anything about each other, and they communicate only through messages (events, commands, packages, etc.) .). At the same time, the same message can have several consumers to execute completely unrelated business logic. So, maintaining an immutable state for the active object, we do not affect one process from another. It can also be part of the security between processes when we execute a message in isolation.

Spring integration is really pure Java, so any concurrency and security restrictions are simply applied here, and you will be surprised at the distribution of the message to various independent processes and see modifications of one process in another.

The reference manual has some information:

Therefore, when a Message instance is sent to several consumers (for example, through the publication publishing channel), if one of these consumers needs to send a response with a different type of payload, it will need to create a new Message . As a result, these changes are not affected by other consumers.

As you can see, it applies to the Message object as such and its MessageHeaders . payload completely up to you, and I really had problems adding and removing elements to the ArrayList payload in multi-threaded business logic.

In any case, the Framework offers a compromise: MutableMessage , MutableMessageHeaders and MutableMessageBuilder . You can also globally override the MessageBuilder used inside the Framework in the MutableMessageBuilderFactory . To do this, you just need to register a bean named bean IntegrationUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME :

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

And all messages in your integration threads will be volatile and will contain the same id and timestamp headers.

+4
source

Source: https://habr.com/ru/post/1274589/


All Articles