INT-789, Added documentation around global channel interceptors.
This commit is contained in:
@@ -70,6 +70,46 @@
|
||||
values. You could obtain the same result by implementing a MessageHandler that did the header modifications
|
||||
and wiring that as a bean.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Some time you need to make a nested call to another chain from within the chain and then come
|
||||
back and continue execution within the original chain.
|
||||
To accomplish this you can utilize Messaging Gateway by including light-configuration via <gateway> element.
|
||||
For example:
|
||||
<programlisting language="xml"><![CDATA[ <si:chain id="main-chain" input-channel="inputA" output-channel="inputB">
|
||||
<si:header-enricher>
|
||||
<si:header name="name" value="Many" />
|
||||
</si:header-enricher>
|
||||
<si:service-activator>
|
||||
<bean class="org.foo.SampleService" />
|
||||
</si:service-activator>
|
||||
<si:gateway request-channel="inputC"/>
|
||||
</si:chain>
|
||||
<si:chain id="nested-chain-a" input-channel="inputC">
|
||||
<si:header-enricher>
|
||||
<si:header name="name" value="Moe" />
|
||||
</si:header-enricher>
|
||||
<si:gateway request-channel="inputD"/>
|
||||
<si:service-activator>
|
||||
<bean class="org.foo.SampleService" />
|
||||
</si:service-activator>
|
||||
</si:chain>
|
||||
<si:chain id="nested-chain-b" input-channel="inputD">
|
||||
<si:header-enricher>
|
||||
<si:header name="name" value="Jack" />
|
||||
</si:header-enricher>
|
||||
<si:service-activator>
|
||||
<bean class="org.foo.SampleService" />
|
||||
</si:service-activator>
|
||||
</si:chain>]]></programlisting>
|
||||
|
||||
In the above example the <emphasis>nested-chain-a</emphasis> will be called at the end of <emphasis>main-chain</emphasis> processing by the 'gateway' element
|
||||
configured there. While in <emphasis>nested-chain-a</emphasis> a call to a <emphasis>nested-chain-b</emphasis> will be made after header enrichment and then it will
|
||||
come back to finish execution in <emphasis>nested-chain-b</emphasis> finally getting back to the <emphasis>main-chain</emphasis>.
|
||||
When light version of <gateway> element is defined in the chain SI will construct an instance <classname>SimpleMessagingGateway</classname>
|
||||
(no need to provide 'service-interface' configuration) which will take the message in its current state and will place it on the channel defined via 'request-channel' attribute.
|
||||
Upon processing <classname>Message</classname> will be returned to the gateway and continue its journey within the current chain.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
@@ -523,6 +523,40 @@ public Message<?> receive(final PollableChannel<?> channel) { ... }]]></programl
|
||||
usually provide common behavior that can be reused across multiple channels.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="global-channel-configuration-interceptors">
|
||||
<title>Global Channel Interceptor Configuration</title>
|
||||
<para>
|
||||
Channel Interceptors allow you for a clean and concise way of applying cross-cutting behavior per individual channel.
|
||||
But what if the same behavior should be applied on multiple channels, configuring the same set of interceptors for
|
||||
each channel <emphasis>would not be</emphasis> the most efficient way. The better way would be to configure interceptors globally and apply
|
||||
them on multiple channels in one shot. Spring Integration provides capabilities to configure <emphasis>Global Interceptor Chains</emphasis>
|
||||
and apply them on multiple channels.
|
||||
Look at the example below:
|
||||
<programlisting language="xml"><![CDATA[<int:channel-interceptor-chain channel-name-pattern="input*, bar*, foo" order="3">
|
||||
<bean class="foo.barSampleInterceptor"/>
|
||||
<ref bean="someOtherInterceptor"/>
|
||||
</int:channel-interceptor-chain>]]></programlisting>
|
||||
<channel-interceptor-chain> element will assemble the chain of interceptors and will apply them on all the
|
||||
channels defined in the <channel-name-patter> attribute. In the above case the two interceptors that are defined
|
||||
within the chain are going to be applied on 'foo' channel and all other channels that begin with 'bar' and 'input'.
|
||||
The <order> attribute allows you to manage the place where this interceptor chain will be injected.
|
||||
For example, channel 'inputChannel' could have individual interceptors configured locally (see below):
|
||||
<programlisting language="xml"><![CDATA[<int:channel id="inputChannel">
|
||||
<int:interceptors>
|
||||
<int:wire-tap channel="logger"/>
|
||||
</int:interceptors>
|
||||
</int:channel>]]></programlisting>
|
||||
The reasonable question would be where interceptors defined by <emphasis>channel-interceptor-cahin</emphasis> should be injected
|
||||
in relation to the existing one(s) (configured locally or through other global chains)? Current implementation provides
|
||||
a very simple and clever mechanism of handling this. Positive number in the <emphasis>order</emphasis> attribute will ensure interceptor injection
|
||||
after existing interceptors and negative number will ensure that such interceptors injected before.
|
||||
This means that in the above example interceptors configured in global interceptor chain would be injected after
|
||||
'wire-tap' interceptor configured locally. If there was another global chain with matching <emphasis>channel-name-pattern</emphasis> the
|
||||
order between the interceptors defined in two chains would be determined based on who's got the higher or lower
|
||||
value in <emphasis>order</emphasis> attribute.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="channel-wiretap">
|
||||
<title>Wire Tap</title>
|
||||
|
||||
Reference in New Issue
Block a user