I'm testing the behavior of the .channel() method and I've observed things that I don't understand.
@Bean
public IntegrationFlow flow() {
return IntegrationFlows.from("my-gateway")
.channel("first-channel")
.channel("second-channel")
.get();
}
If I place print statements in "first-channel", they aren't printed. But some of the business logic still appears to happen. Edit: Added code for service activators
@ServiceActivator(inputChannel = "first-channel")
public Message testFlow(Message message) {
System.out.println("Entered First Channel " + "\n" + "Message Header: " + message.getHeaders() + "\n" + "Message Payload" + "\n" + message.getPayload());
return message;
}
@ServiceActivator(inputChannel = "second-channel")
public Message testFlow(Message message) {
System.out.println("Entered Second Channel " + "\n" + "Message Header: " + message.getHeaders() + "\n" + "Message Payload" + "\n" + message.getPayload());
return message;
}
application.properties:
logging.level.root=TRACE
Am I allowed to pass a message through multiple channels in the same java dsl IntegrationFlow? Or are all IntegrationFlows restricted to one channel/ServiceActivator each?
Edit: Only the second print statement appears in the logs. Why is that?
No, you definitely can build a flow with multiple channels and you even can have a configuration like that. A bridge()
is placed in between then internally by the framework. Image you need to dump messages from direct call to some queue or vise versa. Or your message channel even can be based on some persistent storage for messages like JMS, AMQP etc.
The MessageChannel
abstraction is a first-class citizen in Spring Integration and that comes from the canonical integration model described in the EIP: https://www.enterpriseintegrationpatterns.com/patterns/messaging/MessageChannel.html
The importance of such an implementation between endpoints comes handy when see how those endpoints are loosely-coupled and the target MessageChannel
implementation may dictate us some behavior change in the middle of the flow.
Another aspect as an argument that it is valid to have a flow like you define is a ChannelInterceptor
. You still may have definition with just channel names, but ChannelInterceptor
can be applied to them globally according its pattern option.
The opposite is also true: you can declare a flow just only with endpoints and the framework places channel in between internally.
Please, see docs for more info: https://docs.spring.io/spring-integration/docs/5.2.3.RELEASE/reference/html/dsl.html#java-dsl