1
1
/*
2
- * Copyright 2002-2018 the original author or authors.
2
+ * Copyright 2002-2019 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
24
24
import java .util .List ;
25
25
import java .util .Map ;
26
26
import java .util .Set ;
27
- import java .util .concurrent .ConcurrentHashMap ;
28
27
import java .util .function .Predicate ;
29
28
30
29
import org .apache .commons .logging .Log ;
35
34
import org .springframework .context .ApplicationContext ;
36
35
import org .springframework .context .ApplicationContextAware ;
37
36
import org .springframework .core .MethodIntrospector ;
38
- import org .springframework .core .MethodParameter ;
39
37
import org .springframework .core .ReactiveAdapterRegistry ;
40
38
import org .springframework .lang .Nullable ;
41
39
import org .springframework .messaging .Message ;
42
- import org .springframework .messaging .MessageHandlingException ;
43
40
import org .springframework .messaging .MessagingException ;
44
41
import org .springframework .messaging .ReactiveMessageHandler ;
45
42
import org .springframework .messaging .handler .HandlerMethod ;
@@ -82,20 +79,14 @@ public abstract class AbstractMethodMessageHandler<T>
82
79
protected final Log logger = LogFactory .getLog (getClass ());
83
80
84
81
82
+ @ Nullable
83
+ private Predicate <Class <?>> handlerPredicate ;
84
+
85
85
private ArgumentResolverConfigurer argumentResolverConfigurer = new ArgumentResolverConfigurer ();
86
86
87
87
private ReturnValueHandlerConfigurer returnValueHandlerConfigurer = new ReturnValueHandlerConfigurer ();
88
88
89
- private final HandlerMethodArgumentResolverComposite argumentResolvers =
90
- new HandlerMethodArgumentResolverComposite ();
91
-
92
- private final HandlerMethodReturnValueHandlerComposite returnValueHandlers =
93
- new HandlerMethodReturnValueHandlerComposite ();
94
-
95
- private ReactiveAdapterRegistry reactiveAdapterRegistry = ReactiveAdapterRegistry .getSharedInstance ();
96
-
97
- @ Nullable
98
- private Predicate <Class <?>> handlerPredicate ;
89
+ private final InvocableHelper invocableHelper = new InvocableHelper (this ::createExceptionMethodResolverFor );
99
90
100
91
@ Nullable
101
92
private ApplicationContext applicationContext ;
@@ -104,12 +95,24 @@ public abstract class AbstractMethodMessageHandler<T>
104
95
105
96
private final MultiValueMap <String , T > destinationLookup = new LinkedMultiValueMap <>(64 );
106
97
107
- private final Map <Class <?>, AbstractExceptionHandlerMethodResolver > exceptionHandlerCache =
108
- new ConcurrentHashMap <>(64 );
109
98
110
- private final Map <MessagingAdviceBean , AbstractExceptionHandlerMethodResolver > exceptionHandlerAdviceCache =
111
- new LinkedHashMap <>(64 );
99
+ /**
100
+ * Configure a predicate to decide if which beans in the Spring context
101
+ * should be checked to see if they have message handling methods.
102
+ * <p>By default this is not set and sub-classes should configure it in
103
+ * order to enable auto-detection of message handling methods.
104
+ */
105
+ public void setHandlerPredicate (@ Nullable Predicate <Class <?>> handlerPredicate ) {
106
+ this .handlerPredicate = handlerPredicate ;
107
+ }
112
108
109
+ /**
110
+ * Return the {@link #setHandlerPredicate configured} handler predicate.
111
+ */
112
+ @ Nullable
113
+ public Predicate <Class <?>> getHandlerPredicate () {
114
+ return this .handlerPredicate ;
115
+ }
113
116
114
117
/**
115
118
* Configure custom resolvers for handler method arguments.
@@ -141,39 +144,20 @@ public ReturnValueHandlerConfigurer getReturnValueHandlerConfigurer() {
141
144
return this .returnValueHandlerConfigurer ;
142
145
}
143
146
144
- /**
145
- * Configure a predicate to decide if which beans in the Spring context
146
- * should be checked to see if they have message handling methods.
147
- * <p>By default this is not set and sub-classes should configure it in
148
- * order to enable auto-detection of message handling methods.
149
- */
150
- public void setHandlerPredicate (@ Nullable Predicate <Class <?>> handlerPredicate ) {
151
- this .handlerPredicate = handlerPredicate ;
152
- }
153
-
154
- /**
155
- * Return the {@link #setHandlerPredicate configured} handler predicate.
156
- */
157
- @ Nullable
158
- public Predicate <Class <?>> getHandlerPredicate () {
159
- return this .handlerPredicate ;
160
- }
161
-
162
147
/**
163
148
* Configure the registry for adapting various reactive types.
164
149
* <p>By default this is an instance of {@link ReactiveAdapterRegistry} with
165
150
* default settings.
166
151
*/
167
152
public void setReactiveAdapterRegistry (ReactiveAdapterRegistry registry ) {
168
- Assert .notNull (registry , "ReactiveAdapterRegistry is required" );
169
- this .reactiveAdapterRegistry = registry ;
153
+ this .invocableHelper .setReactiveAdapterRegistry (registry );
170
154
}
171
155
172
156
/**
173
157
* Return the configured registry for adapting reactive types.
174
158
*/
175
159
public ReactiveAdapterRegistry getReactiveAdapterRegistry () {
176
- return this .reactiveAdapterRegistry ;
160
+ return this .invocableHelper . getReactiveAdapterRegistry () ;
177
161
}
178
162
179
163
@ Override
@@ -193,7 +177,7 @@ public ApplicationContext getApplicationContext() {
193
177
protected void registerExceptionHandlerAdvice (
194
178
MessagingAdviceBean bean , AbstractExceptionHandlerMethodResolver resolver ) {
195
179
196
- this .exceptionHandlerAdviceCache . put (bean , resolver );
180
+ this .invocableHelper . registerExceptionHandlerAdvice (bean , resolver );
197
181
}
198
182
199
183
/**
@@ -219,13 +203,13 @@ public void afterPropertiesSet() {
219
203
if (resolvers .isEmpty ()) {
220
204
resolvers = new ArrayList <>(this .argumentResolverConfigurer .getCustomResolvers ());
221
205
}
222
- this .argumentResolvers . addResolvers (resolvers );
206
+ this .invocableHelper . addArgumentResolvers (resolvers );
223
207
224
208
List <? extends HandlerMethodReturnValueHandler > handlers = initReturnValueHandlers ();
225
209
if (handlers .isEmpty ()) {
226
210
handlers = new ArrayList <>(this .returnValueHandlerConfigurer .getCustomHandlers ());
227
211
}
228
- this .returnValueHandlers . addHandlers (handlers );
212
+ this .invocableHelper . addReturnValueHandlers (handlers );
229
213
230
214
initHandlerMethods ();
231
215
}
@@ -379,21 +363,7 @@ public Mono<Void> handleMessage(Message<?> message) throws MessagingException {
379
363
return Mono .empty ();
380
364
}
381
365
HandlerMethod handlerMethod = match .getHandlerMethod ().createWithResolvedBean ();
382
- InvocableHandlerMethod invocable = new InvocableHandlerMethod (handlerMethod );
383
- invocable .setArgumentResolvers (this .argumentResolvers .getResolvers ());
384
- if (logger .isDebugEnabled ()) {
385
- logger .debug ("Invoking " + invocable .getShortLogMessage ());
386
- }
387
- return invocable .invoke (message )
388
- .flatMap (value -> {
389
- MethodParameter returnType = invocable .getReturnType ();
390
- return this .returnValueHandlers .handleReturnValue (value , returnType , message );
391
- })
392
- .onErrorResume (throwable -> {
393
- Exception ex = (throwable instanceof Exception ) ? (Exception ) throwable :
394
- new MessageHandlingException (message , "HandlerMethod invocation error" , throwable );
395
- return processHandlerException (message , handlerMethod , ex );
396
- });
366
+ return this .invocableHelper .handleMessage (handlerMethod , message );
397
367
}
398
368
399
369
@ Nullable
@@ -482,68 +452,6 @@ protected void handleNoMatch(@Nullable String destination, Message<?> message) {
482
452
logger .debug ("No handlers for destination '" + destination + "'" );
483
453
}
484
454
485
-
486
- private Mono <Void > processHandlerException (Message <?> message , HandlerMethod handlerMethod , Exception ex ) {
487
- InvocableHandlerMethod exceptionInvocable = findExceptionHandler (handlerMethod , ex );
488
- if (exceptionInvocable == null ) {
489
- logger .error ("Unhandled exception from message handling method" , ex );
490
- return Mono .error (ex );
491
- }
492
- exceptionInvocable .setArgumentResolvers (this .argumentResolvers .getResolvers ());
493
- if (logger .isDebugEnabled ()) {
494
- logger .debug ("Invoking " + exceptionInvocable .getShortLogMessage ());
495
- }
496
- return exceptionInvocable .invoke (message , ex )
497
- .flatMap (value -> {
498
- MethodParameter returnType = exceptionInvocable .getReturnType ();
499
- return this .returnValueHandlers .handleReturnValue (value , returnType , message );
500
- });
501
- }
502
-
503
- /**
504
- * Find an exception handling method for the given exception.
505
- * <p>The default implementation searches methods in the class hierarchy of
506
- * the HandlerMethod first and if not found, it continues searching for
507
- * additional handling methods registered via
508
- * {@link #registerExceptionHandlerAdvice(MessagingAdviceBean, AbstractExceptionHandlerMethodResolver)}.
509
- * @param handlerMethod the method where the exception was raised
510
- * @param exception the raised exception
511
- * @return a method to handle the exception, or {@code null}
512
- */
513
- @ Nullable
514
- protected InvocableHandlerMethod findExceptionHandler (HandlerMethod handlerMethod , Exception exception ) {
515
- if (logger .isDebugEnabled ()) {
516
- logger .debug ("Searching for methods to handle " + exception .getClass ().getSimpleName ());
517
- }
518
- Class <?> beanType = handlerMethod .getBeanType ();
519
- AbstractExceptionHandlerMethodResolver resolver = this .exceptionHandlerCache .get (beanType );
520
- if (resolver == null ) {
521
- resolver = createExceptionMethodResolverFor (beanType );
522
- this .exceptionHandlerCache .put (beanType , resolver );
523
- }
524
- InvocableHandlerMethod exceptionHandlerMethod = null ;
525
- Method method = resolver .resolveMethod (exception );
526
- if (method != null ) {
527
- exceptionHandlerMethod = new InvocableHandlerMethod (handlerMethod .getBean (), method );
528
- }
529
- else {
530
- for (MessagingAdviceBean advice : this .exceptionHandlerAdviceCache .keySet ()) {
531
- if (advice .isApplicableToBeanType (beanType )) {
532
- resolver = this .exceptionHandlerAdviceCache .get (advice );
533
- method = resolver .resolveMethod (exception );
534
- if (method != null ) {
535
- exceptionHandlerMethod = new InvocableHandlerMethod (advice .resolveBean (), method );
536
- break ;
537
- }
538
- }
539
- }
540
- }
541
- if (exceptionHandlerMethod != null ) {
542
- exceptionHandlerMethod .setArgumentResolvers (this .argumentResolvers .getResolvers ());
543
- }
544
- return exceptionHandlerMethod ;
545
- }
546
-
547
455
/**
548
456
* Create a concrete instance of {@link AbstractExceptionHandlerMethodResolver}
549
457
* that finds exception handling methods based on some criteria, e.g. based
0 commit comments