Dear Spring community,

We are pleased to announce that the Spring Integration 4.1 Release Candidate is available.

Please use the Milestone Repository with Maven or Gradle, or download a distribution archive, to give it a spin.

The release includes many new features and improvements, as well as a number of bug fixes. The GA release

is planned in early November.

First of all, thank you all who provided feedback for the

4.1 Milestone 1 and

submitted reports (bugs or new features). A special thanks to those who provided contribution via Pull Requests.

Here is a summary of major changes since the milestone:

Web Sockets support

This feature was introduced in 4.1 Milestone 1, but several issues have been resolved, and we have now

provided a couple of samples to better understand how Web Sockets can be used in Spring Integration applications:

Basic and

STOMP Chat.

JDK8 Optional<?> consistent handling

If you are using Java 8, you’ll be able to use the Optional<?> container for service method arguments. For example:

public void optionals(@Payload("@myConvert.conv(payload)") Optional<Bar> payload, @Header(value="foo") Optional<String> header)

In this case, if @myConvert.conv(payload) returns null , the payload variable will contain an Optional.empty() .

The same thing for header variables - if there is no foo header in the request Message<?> . This can be used

as an alternative to the required attribute on a @Header annotation.

Routing Slip pattern

The Routing Slip pattern is now supported. Rather

than a simple static list of channel names , we have introduced the RoutingSlipRouteStrategy , which provides

dynamic runtime routing based on the request Message<?> and reply object . SpEL is supported too:

<header-enricher input-channel="input" output-channel="process"> <routing-slip value="channel1; request.headers[myRoutingSlipChannel]; routingSlipRoutingStrategy;"/> </header-enricher>

This pattern is useful in complex, dynamic, cases when it can become difficult to configure multiple routers to determine

message flow. With this enhancement, when a message

arrives at an endpoint that has no output-channel , the routing slip is consulted to determine the next channel to which

the message will be sent. When the routing slip is exhausted, normal replyChannel processing resumes.

Idempotent Receiver pattern

With this release we have implemented the

Idempotent Receiver as a first class feature.

Previously, users would have to implement this pattern, by using a custom MessageSelector in a <filter/> , for example.

The framework now supports this capability as an Advice component that can be applied to any consuming endpoint:

<idempotent-receiver endpoint="endpoint1, foo*" metadata-store="store" discard-channel="duplicates" key-expression="payload.invoiceNumber"/>

This creates an AOP IdempotentReceiverInterceptor which is applied to the MessageHandler#handleMessage within endpoints

where the id matches one of the provided endpoint patterns.

If the discard-channel is omitted, a duplicate message is still sent to the message handler, but it will contain a

duplicateMessage header, allowing user code to take further action.

For JavaConfig, the @IdempotentReceiver annotation is provided, however the IdempotentReceiverInterceptor @Bean must

be configured too:

````java

@Bean

public IdempotentReceiverInterceptor idempotentReceiverInterceptor() {

return new IdempotentReceiverInterceptor(new MetadataStoreSelector(m ->

m.getPayload().toString()));

}

@Bean

@ServiceActivator(inputChannel = “input”, outputChannel = “output”)

@IdempotentReceiver(“idempotentReceiverInterceptor”)

public MessageHandler myService() {

….

}

````

For more information, please, read IdempotentReceiverInterceptor JavaDocs.

Scatter-Gather pattern

The Scatter-Gather

Enterprise Integration Pattern is now provided:

<!--Auction scenario--> <scatter-gather input-channel="inputAuction" output-channel="output" scatter-channel="auctionChannel"> <gatherer release-strategy-expression="^[payload gt 5] != null or size() == 3"/> </scatter-gather> <!--Distribution scenario--> <scatter-gather input-channel="inputDistribution" output-channel="output" gather-channel="gatherChannel"> <scatterer apply-sequence="true"> <recipient channel="distribution1Channel"/> <recipient channel="distribution2Channel"/> <recipient channel="distribution3Channel"/> </scatterer> <gatherer release-strategy-expression="^[payload gt 5] != null or size() == 3"/> </scatter-gather>

It is a compound endpoint, which combines publish-subscribe logic and an aggregation function.

Of course, it could previously be implemented as an integration flow using the existing publish-subscribe-channel ,

or recipient-list-router , together with an aggregator

component, but this new feature provides for a cleaner implementation of scenarios such as best quote .

Redis Queue Gateways

A pair of request-reply (inbound and outbound) gateway components based on Redis List s have been added to the Redis module:

<int-redis:queue-outbound-gateway request-channel="sendChannel" queue="foo"/> <int-redis:queue-inbound-gateway request-channel="requestChannel" queue="foo"/>

Reactor’s PersistentQueue

The QueueChannel has been changed to allow inject any Queue<?> implementation. This was done to allow the

use of the Chronicle-Queue implementation in the Reactor project:

@Bean QueueChannel queueChannel() { return new QueueChannel(new PersistentQueueSpec<Message<?>>() .codec(new JavaSerializationCodec<>()) .basePath("/usr/queuePath") .get()); }

Skipping Polls

When using polling endpoints, it is sometimes necessary to “skip” polls, perhaps because some downstream condition might

cause a failure or, say, a task executor pool has no available threads. This release adds the PollSkipAdvice that

can be inserted in the poller’s advice chain, with the skip logic based on user-supplied code.

Notes

Spring Integration 4.1 requires Spring Framework 4.1 While JDK8 is now required to build Spring Integration, the framework remains compatible with Java 6 at runtime. We expect to announce the availability of the Spring Integration Java DSL release candidate later this week.

Conclusion

See the Release Notes for this release

and the Project Page for more information. For a complete

list of “What’s new” in the 4.1 release, see the reference documentation. Users upgrading from earlier releases should consult the various migration guides.

As always, we very much welcome contributions.