@@ -120,8 +120,8 @@ public final void setAsync(boolean async) {
120
120
121
121
/**
122
122
* @return true if this handler supports async replies.
123
- * @since 4.3
124
123
* @see #setAsync(boolean)
124
+ * @since 4.3
125
125
*/
126
126
protected boolean isAsync () {
127
127
return this .async ;
@@ -133,8 +133,8 @@ protected boolean isAsync() {
133
133
* {@link #shouldCopyRequestHeaders() shouldCopyRequestHeaaders} is true.
134
134
* At least one pattern as "*" means do not copy headers at all.
135
135
* @param headers the headers to not propagate from the inbound message.
136
- * @since 4.3.10
137
136
* @see org.springframework.util.PatternMatchUtils
137
+ * @since 4.3.10
138
138
*/
139
139
@ Override
140
140
public void setNotPropagatedHeaders (String ... headers ) {
@@ -190,8 +190,7 @@ public Collection<String> getNotPropagatedHeaders() {
190
190
/**
191
191
* Add header patterns ("xxx*", "*xxx", "*xxx*" or "xxx*yyy")
192
192
* that will NOT be copied from the inbound message if
193
- * {@link #shouldCopyRequestHeaders()} is true, instead of overwriting the existing
194
- * set.
193
+ * {@link #shouldCopyRequestHeaders()} is true, instead of overwriting the existing set.
195
194
* @param headers the headers to not propagate from the inbound message.
196
195
* @since 4.3.10
197
196
* @see #setNotPropagatedHeaders(String...)
@@ -310,28 +309,68 @@ private void doProduceOutput(Message<?> requestMessage, MessageHeaders requestHe
310
309
replyChannel = getOutputChannel ();
311
310
}
312
311
313
- if (this .async && (reply instanceof org .springframework .util .concurrent .ListenableFuture <?>
314
- || reply instanceof CompletableFuture <?>
315
- || reply instanceof Publisher <?>)) {
312
+ ReactiveAdapter reactiveAdapter = null ;
316
313
317
- if (reply instanceof Publisher <?> &&
318
- replyChannel instanceof ReactiveStreamsSubscribableChannel ) {
314
+ if (this .async &&
315
+ (reply instanceof org .springframework .util .concurrent .ListenableFuture <?>
316
+ || reply instanceof CompletableFuture <?>
317
+ || (reactiveAdapter = ReactiveAdapterRegistry .getSharedInstance ().getAdapter (null , reply )) != null )) {
319
318
320
- ((ReactiveStreamsSubscribableChannel ) replyChannel )
319
+ if (replyChannel instanceof ReactiveStreamsSubscribableChannel reactiveStreamsSubscribableChannel ) {
320
+ Publisher <?> reactiveReply = toPublisherReply (reply , reactiveAdapter );
321
+ reactiveStreamsSubscribableChannel
321
322
.subscribeTo (
322
- Flux .from (( Publisher <?>) reply )
323
+ Flux .from (reactiveReply )
323
324
.doOnError ((ex ) -> sendErrorMessage (requestMessage , ex ))
324
325
.map (result -> createOutputMessage (result , requestHeaders )));
325
326
}
326
327
else {
327
- asyncNonReactiveReply (requestMessage , reply , replyChannel );
328
+ CompletableFuture <?> futureReply = toFutureReply (reply , reactiveAdapter );
329
+ futureReply .whenComplete (new ReplyFutureCallback (requestMessage , replyChannel ));
328
330
}
329
331
}
330
332
else {
331
333
sendOutput (createOutputMessage (reply , requestHeaders ), replyChannel , false );
332
334
}
333
335
}
334
336
337
+ private static Publisher <?> toPublisherReply (Object reply , @ Nullable ReactiveAdapter reactiveAdapter ) {
338
+ if (reactiveAdapter != null ) {
339
+ return reactiveAdapter .toPublisher (reply );
340
+ }
341
+ else {
342
+ return Mono .fromFuture (toCompletableFuture (reply ));
343
+ }
344
+ }
345
+
346
+ private static CompletableFuture <?> toFutureReply (Object reply , @ Nullable ReactiveAdapter reactiveAdapter ) {
347
+ if (reactiveAdapter != null ) {
348
+ Mono <?> reactiveReply ;
349
+ Publisher <?> publisher = reactiveAdapter .toPublisher (reply );
350
+ if (reactiveAdapter .isMultiValue ()) {
351
+ reactiveReply = Mono .just (publisher );
352
+ }
353
+ else {
354
+ reactiveReply = Mono .from (publisher );
355
+ }
356
+
357
+ return reactiveReply .publishOn (Schedulers .boundedElastic ()).toFuture ();
358
+ }
359
+ else {
360
+ return toCompletableFuture (reply );
361
+ }
362
+ }
363
+
364
+ @ SuppressWarnings ("deprecation" )
365
+ private static CompletableFuture <?> toCompletableFuture (Object reply ) {
366
+ if (reply instanceof CompletableFuture <?>) {
367
+ return (CompletableFuture <?>) reply ;
368
+ }
369
+ else {
370
+ return ((org .springframework .util .concurrent .ListenableFuture <?>) reply ).completable ();
371
+ }
372
+ }
373
+
335
374
private AbstractIntegrationMessageBuilder <?> addRoutingSlipHeader (Object reply , List <?> routingSlip ,
336
375
AtomicInteger routingSlipIndex ) {
337
376
@@ -354,30 +393,6 @@ else if (reply instanceof AbstractIntegrationMessageBuilder) {
354
393
return builder ;
355
394
}
356
395
357
- @ SuppressWarnings ("deprecation" )
358
- private void asyncNonReactiveReply (Message <?> requestMessage , Object reply , @ Nullable Object replyChannel ) {
359
- CompletableFuture <?> future ;
360
- if (reply instanceof CompletableFuture <?>) {
361
- future = (CompletableFuture <?>) reply ;
362
- }
363
- else if (reply instanceof org .springframework .util .concurrent .ListenableFuture <?>) {
364
- future = ((org .springframework .util .concurrent .ListenableFuture <?>) reply ).completable ();
365
- }
366
- else {
367
- Mono <?> reactiveReply ;
368
- ReactiveAdapter adapter = ReactiveAdapterRegistry .getSharedInstance ().getAdapter (null , reply );
369
- if (adapter != null && adapter .isMultiValue ()) {
370
- reactiveReply = Mono .just (reply );
371
- }
372
- else {
373
- reactiveReply = Mono .from ((Publisher <?>) reply );
374
- }
375
-
376
- future = reactiveReply .publishOn (Schedulers .boundedElastic ()).toFuture ();
377
- }
378
- future .whenComplete (new ReplyFutureCallback (requestMessage , replyChannel ));
379
- }
380
-
381
396
private Object getOutputChannelFromRoutingSlip (Object reply , Message <?> requestMessage , List <?> routingSlip ,
382
397
AtomicInteger routingSlipIndex ) {
383
398
@@ -446,7 +461,7 @@ else if (output instanceof AbstractIntegrationMessageBuilder) {
446
461
* <code>null</code>, and it must be an instance of either String or {@link MessageChannel}.
447
462
* @param output the output object to send
448
463
* @param replyChannelArg the 'replyChannel' value from the original request
449
- * @param useArgChannel - use the replyChannel argument (must not be null), not
464
+ * @param useArgChannel use the replyChannel argument (must not be null), not
450
465
* the configured output channel.
451
466
*/
452
467
protected void sendOutput (Object output , @ Nullable Object replyChannelArg , boolean useArgChannel ) {
0 commit comments