No; the interceptor only becomes the 'listener' in wrapConnection if there is no real listener for this connection (it is a send-only connection).
For connections that can receive messages, we register a listener with the connection - this is usually a receiving channel adapter, or a gateway.
We can also register a sender with a connection, this is the object that sends messages (either an outbound adapter or a gateway).
Now, TcpConnectionInterceptor extends TcpConnection, TcpListener, and TcpSender.
In the wrapConnection method, for each interceptor in the chain, the interceptor (variable 'wrapper') is given a reference to the connection.
In the case of a gateway, there is always a listener and sender. So, for each interceptor in the chain, the interceptor is given a reference to the connection and this interceptor becomes the new "connection"; if there are two interceptors, the first gets a reference to the the real connection, the second gets a reference to the first interceptor. We finally return the second interceptor as "the" connection.
Finally, in initializeConnection(), we register the listener (gateway) with "the" connection (which is our second interceptor in this case).
registerListener() in AbstractTcpConnectionInterceptor looks like this...
Code:
public void registerListener(TcpListener listener) {
this.theConnection.registerListener(this);
this.tcpListener = listener;
}
This effectively chains the interceptors - interceptor 2's listener is the gateway, interceptor 1's listener is interceptor 2, the real connection's listener is interceptor 1. Now, when a new message is assembled, the message is passed up through the interceptor chain.
If you want to see it in action, check out the source from git and take a look at InterceptedSharedConnectionTests where I nested two hello world interceptors. These interceptors do some handshaking during the initial send.
Code:
<bean id="helloWorldInterceptors" class="org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorFactoryChain">
<property name="interceptors">
<array>
<bean class="org.springframework.integration.ip.tcp.connection.HelloWorldInterceptorFactory"/>
<bean class="org.springframework.integration.ip.tcp.connection.HelloWorldInterceptorFactory">
<constructor-arg value="Hi"/>
<constructor-arg value="planet!"/>
</bean>
</array>
</property>
</bean>
On the client side, when we send a message, the second (outer) interceptor sees negotiation is needed so holds on to the original messge and sends 'Hi' which is intercepted by the inner interceptor who also needs negotiation, so he holds on to the 'Hi' sends 'Hello' and . On the server side, the inner interceptor sees the Hello and sends 'world!' which is received by the inner client interceptor and because negotiation is complete, sends on the 'Hi'. On the server side, the inner interceptor is fully negotiated so he passes the Hi up the chain; the outer interceptor completes his negotiation and, eventually, the original payload is sent and from that point on, both interceptors are pass-throughs.
Code:
2010-12-22 11:29:06,564 DEBUG [main] DirectChannel: preSend on channel 'input', message: [Payload=Test][Headers={timestamp=1293035346564, id=bd9cb8e6-39b6-4486-a1ae-132dba8840f2}]
...
2010-12-22 11:29:06,576 DEBUG [main] HelloWorldInterceptor: Sending Hi
2010-12-22 11:29:06,576 DEBUG [main] HelloWorldInterceptor: Sending Hello
...
2010-12-22 11:29:06,585 DEBUG [pool-1-thread-3] HelloWorldInterceptor: sending world!
...
2010-12-22 11:29:06,587 DEBUG [pool-2-thread-3] HelloWorldInterceptor: received world!
...
2010-12-22 11:29:06,619 DEBUG [pool-1-thread-2] HelloWorldInterceptor: sending planet!
...
2010-12-22 11:29:06,661 DEBUG [pool-2-thread-5] HelloWorldInterceptor: received planet!
...
2010-12-22 11:29:06,662 DEBUG [main] DirectChannel: postSend (sent=true) on channel 'input', message: [Payload=Test][Headers={timestamp=1293035346564, id=bd9cb8e6-39b6-4486-a1ae-132dba8840f2}]
...
2010-12-22 11:29:06,702 DEBUG [main] QueueChannel: postReceive on channel 'replies', message: [Payload=Test][Headers={timestamp=1293035346702, id=cad2f313-16ba-48ee-9173-beef6dce86c5, ip_address=127.0.0.1, ip_connection_seq=3, ip_hostname=localhost, ip_tcp_remote_port=10100, ip_connection_id=localhost:10100:1022146175}]
BTW, the interceptor chain was conceived for doing handshaking/negotiation such as this, but we did foresee that it might be used for other things, so I am pleased we were able to use it as a work-around for your problem.