You could do it that way, but you'd need a transformer/header-enricher on each leg to populate a header with the correlation data.
need to correlate the response to the request?
Synchronizing won't help; the framework needs some way to figure out where to send the reply.
For your application, I would recommend doing something like this...
Code:
public class Foo {
private final Log logger = LogFactory.getLog(this.getClass().getName());
private final Map<String, BlockingQueue<String>> pendingReplies = new ConcurrentHashMap<String, BlockingQueue<String>>();
@Autowired
private RequestHandler requestHandler;
public String getCreditReport(String personID) {
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
this.pendingReplies.put(personID, queue);
this.requestHandler.send(personID);
String reply = null;
try {
reply = queue.poll(10, TimeUnit.SECONDS);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
this.pendingReplies.remove(personID);
if (reply == null) {
throw new RuntimeException("No reply from credit service");
}
return reply;
}
public void handleReply(String reply) {
String personID = lookup(reply);
BlockingQueue<String> queue = this.pendingReplies.get(personID);
if (queue == null) {
logger.error("Reply too late:" + reply);
}
else {
try {
queue.put(reply);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
this.pendingReplies.remove(personID);
}
}
private String lookup(String reply) {
// find personID in reply
return reply;
}
public interface RequestHandler {
void send(String personID);
}
}
Code:
<context:annotation-config />
<bean id="client" class="foo.Foo" />
<int:gateway id="requestHandler" service-interface="foo.Foo$RequestHandler"
default-request-channel="foo"/>
<int:channel id="foo" />
...
<!-- INBOUND -- >
...
<int:service-activator input-channel="bar"
ref="client" method="handleReply"/>