Skip to content
This repository has been archived by the owner on Jul 9, 2022. It is now read-only.

Working With Closures

dturanski edited this page Oct 29, 2012 · 4 revisions

One of the most compelling features of the Spring Integration Groovy DSL is the ability to implement logic for EIP endpoints such as transformers, filters, routers, splitters, and aggregators as Groovy closures, defined in line. This works whether your application is written in Groovy or Java (I haven't tried with other JVM languages). A simple example is:

transform('t1',{it.toUpperCase()})

The above defines a transformer named 't1' and a closure, also known as the endpoint action, which operates on the message payload. In this case a String is the expected payload type, although any type that defines the toUpperCase() method will work (this is Groovy after all). If you are unfamiliar with Groovy closure syntax, it is the name used to reference the argument by default. The above is equivalent to:

transform('t1',{payload -> payload.toUpperCase()})

All endpoint actions accept a single argument. A type declaration for the argument is optional. If no type is declared, The payload will be extracted from the Message and passed as the closure argument. If you declare the argument to be of type Message, the Message will be passed to the closure. For example:

transform('t1',{Message msg -> msg.payload.toUpperCase()})

Likewise the return value (implicitly the last line of the closure or explicitly from a return statement) will be wrapped in a Message if necessary. Groovy DSL will respect the type and throw an exception if the argument type does not match the payload type.

If the closure argument is declared as a Map and the message payload is not a Map, the Message headers will be passed to the closure.

Collections

If the closure argument is declared as a collection or array, as in the case of a splitter, the DSL will attempt to coerce the payload to the correct type. If it is declared as a parameterized type and the type parameter is Message or it is declared as a Message array, i.e., Message[] then the collection items will contain messages. Otherwise the items will contain the message payloads

Closure Processing Internals

As closures are not yet supported in Java, the DSL wraps closures in a ClosureInvokingMessageProcessor. The DSL registers each instance as a bean in the integration context using a generated bean name of the form -closureInvokingHandler which will be apparent if you examine the generated XML. For the above example, you will see something like:

<si:transformer id="t1" input-channel="t1.inputChannel" method="processMessage"  
ref="t1_closureInvokingHandler"/>

You will not find a bean named 't1_closureInvokingHandler' in the XML output, since it is registered internally.

Clone this wiki locally