NOTE: It is no longer recommended to use StreamListener in favor of functional programming model.
It will be deprecated and subsequently removed in the future
Annotation that marks a method to be a listener to inputs declared via
EnableBinding
(e.g. channels).
Annotated methods are allowed to have flexible signatures, which determine how the
method is invoked and how their return results are processed. This annotation can be
applied for two separate classes of methods.
Declarative mode
A method is considered declarative if all its method parameter types and return type
(if not void) are binding targets or conversion targets from binding targets via a
registered
StreamListenerParameterAdapter
.
Only declarative methods can have binding targets or conversion targets as arguments
and return type.
Declarative methods must specify what inputs and outputs correspond to their arguments
and return type, and can do this in one of the following ways.
- By using either the
Input
or Output
annotation for each of the
parameters and the Output
annotation on the method for the return type (if
applicable). The use of annotations in this case is mandatory. In this case the
StreamListener
annotation must not specify a value.
- By setting an
Input
bound target as the annotation value of
StreamListener
and using
SendTo
on the method for
the return type (if applicable). In this case the method must have exactly one
parameter, corresponding to an input.
An example of declarative method signature using the former idiom is as follows:
@StreamListener
public @Output("joined") Flux<String> join(
@Input("input1") Flux<String> input1,
@Input("input2") Flux<String> input2) {
// ... join the two input streams via functional operators
}
An example of declarative method signature using the latter idiom is as follows:
@StreamListener(Processor.INPUT)
@SendTo(Processor.OUTPUT)
public Flux<String> convert(Flux<String> input) {
return input.map(String::toUppercase);
}
Declarative methods are invoked only once, when the context is refreshed.
Individual message handler mode
Non declarative methods are treated as message handler based, and are invoked for each
incoming message received from that target. In this case, the method can have a
flexible signature, as described by
MessageMapping
.
If the method returns a
Message
, the result will
be automatically sent to a binding target, as follows:
- A result of the type
Message
will be sent
as-is
- All other results will become the payload of a
Message
The output binding target where the return message is sent is determined by consulting
in the following order:
- The
MessageHeaders
of the resulting
message.
- The value set on the
SendTo
annotation, if
present
An example of individual message handler signature is as follows:
@StreamListener(Processor.INPUT)
@SendTo(Processor.OUTPUT)
public String convert(String input) {
return input.toUppercase();
}