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,15 @@ 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 InvocableHandlerMethodHelper handlerMethodHelper =
90
+ new InvocableHandlerMethodHelper (this ::createExceptionMethodResolverFor );
99
91
100
92
@ Nullable
101
93
private ApplicationContext applicationContext ;
@@ -104,12 +96,24 @@ public abstract class AbstractMethodMessageHandler<T>
104
96
105
97
private final MultiValueMap <String , T > destinationLookup = new LinkedMultiValueMap <>(64 );
106
98
107
- private final Map <Class <?>, AbstractExceptionHandlerMethodResolver > exceptionHandlerCache =
108
- new ConcurrentHashMap <>(64 );
109
99
110
- private final Map <MessagingAdviceBean , AbstractExceptionHandlerMethodResolver > exceptionHandlerAdviceCache =
111
- new LinkedHashMap <>(64 );
100
+ /**
101
+ * Configure a predicate to decide if which beans in the Spring context
102
+ * should be checked to see if they have message handling methods.
103
+ * <p>By default this is not set and sub-classes should configure it in
104
+ * order to enable auto-detection of message handling methods.
105
+ */
106
+ public void setHandlerPredicate (@ Nullable Predicate <Class <?>> handlerPredicate ) {
107
+ this .handlerPredicate = handlerPredicate ;
108
+ }
112
109
110
+ /**
111
+ * Return the {@link #setHandlerPredicate configured} handler predicate.
112
+ */
113
+ @ Nullable
114
+ public Predicate <Class <?>> getHandlerPredicate () {
115
+ return this .handlerPredicate ;
116
+ }
113
117
114
118
/**
115
119
* Configure custom resolvers for handler method arguments.
@@ -141,39 +145,20 @@ public ReturnValueHandlerConfigurer getReturnValueHandlerConfigurer() {
141
145
return this .returnValueHandlerConfigurer ;
142
146
}
143
147
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
148
/**
163
149
* Configure the registry for adapting various reactive types.
164
150
* <p>By default this is an instance of {@link ReactiveAdapterRegistry} with
165
151
* default settings.
166
152
*/
167
153
public void setReactiveAdapterRegistry (ReactiveAdapterRegistry registry ) {
168
- Assert .notNull (registry , "ReactiveAdapterRegistry is required" );
169
- this .reactiveAdapterRegistry = registry ;
154
+ this .handlerMethodHelper .setReactiveAdapterRegistry (registry );
170
155
}
171
156
172
157
/**
173
158
* Return the configured registry for adapting reactive types.
174
159
*/
175
160
public ReactiveAdapterRegistry getReactiveAdapterRegistry () {
176
- return this .reactiveAdapterRegistry ;
161
+ return this .handlerMethodHelper . getReactiveAdapterRegistry () ;
177
162
}
178
163
179
164
@ Override
@@ -193,7 +178,7 @@ public ApplicationContext getApplicationContext() {
193
178
protected void registerExceptionHandlerAdvice (
194
179
MessagingAdviceBean bean , AbstractExceptionHandlerMethodResolver resolver ) {
195
180
196
- this .exceptionHandlerAdviceCache . put (bean , resolver );
181
+ this .handlerMethodHelper . registerExceptionHandlerAdvice (bean , resolver );
197
182
}
198
183
199
184
/**
@@ -219,13 +204,13 @@ public void afterPropertiesSet() {
219
204
if (resolvers .isEmpty ()) {
220
205
resolvers = new ArrayList <>(this .argumentResolverConfigurer .getCustomResolvers ());
221
206
}
222
- this .argumentResolvers .addResolvers (resolvers );
207
+ this .handlerMethodHelper . getArgumentResolvers () .addResolvers (resolvers );
223
208
224
209
List <? extends HandlerMethodReturnValueHandler > handlers = initReturnValueHandlers ();
225
210
if (handlers .isEmpty ()) {
226
211
handlers = new ArrayList <>(this .returnValueHandlerConfigurer .getCustomHandlers ());
227
212
}
228
- this .returnValueHandlers .addHandlers (handlers );
213
+ this .handlerMethodHelper . getReturnValueHandlers () .addHandlers (handlers );
229
214
230
215
initHandlerMethods ();
231
216
}
@@ -379,21 +364,7 @@ public Mono<Void> handleMessage(Message<?> message) throws MessagingException {
379
364
return Mono .empty ();
380
365
}
381
366
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
- });
367
+ return this .handlerMethodHelper .invoke (handlerMethod , message );
397
368
}
398
369
399
370
@ Nullable
@@ -482,68 +453,6 @@ protected void handleNoMatch(@Nullable String destination, Message<?> message) {
482
453
logger .debug ("No handlers for destination '" + destination + "'" );
483
454
}
484
455
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
456
/**
548
457
* Create a concrete instance of {@link AbstractExceptionHandlerMethodResolver}
549
458
* that finds exception handling methods based on some criteria, e.g. based
0 commit comments