18
18
19
19
import java .lang .reflect .AnnotatedElement ;
20
20
import java .lang .reflect .Method ;
21
- import java .lang .reflect .ParameterizedType ;
22
- import java .lang .reflect .Type ;
23
21
import java .nio .charset .Charset ;
24
22
import java .nio .charset .StandardCharsets ;
25
23
import java .util .ArrayList ;
30
28
import java .util .HashSet ;
31
29
import java .util .List ;
32
30
import java .util .Map ;
33
- import java .util .Optional ;
34
31
import java .util .Set ;
35
32
import java .util .concurrent .ConcurrentHashMap ;
36
33
import java .util .concurrent .ConcurrentMap ;
56
53
import org .springframework .amqp .rabbit .listener .RabbitListenerContainerFactory ;
57
54
import org .springframework .amqp .rabbit .listener .RabbitListenerEndpointRegistrar ;
58
55
import org .springframework .amqp .rabbit .listener .RabbitListenerEndpointRegistry ;
56
+ import org .springframework .amqp .rabbit .listener .adapter .AmqpMessageHandlerMethodFactory ;
59
57
import org .springframework .amqp .rabbit .listener .adapter .ReplyPostProcessor ;
60
58
import org .springframework .amqp .rabbit .listener .api .RabbitListenerErrorHandler ;
61
59
import org .springframework .amqp .support .converter .MessageConverter ;
76
74
import org .springframework .beans .factory .config .ConfigurableListableBeanFactory ;
77
75
import org .springframework .context .EnvironmentAware ;
78
76
import org .springframework .context .expression .StandardBeanExpressionResolver ;
79
- import org .springframework .core .MethodParameter ;
80
77
import org .springframework .core .Ordered ;
81
78
import org .springframework .core .annotation .AnnotationUtils ;
82
79
import org .springframework .core .annotation .MergedAnnotations ;
88
85
import org .springframework .core .task .TaskExecutor ;
89
86
import org .springframework .format .support .DefaultFormattingConversionService ;
90
87
import org .springframework .lang .Nullable ;
91
- import org .springframework .messaging .Message ;
92
88
import org .springframework .messaging .converter .GenericMessageConverter ;
93
89
import org .springframework .messaging .handler .annotation .support .DefaultMessageHandlerMethodFactory ;
94
90
import org .springframework .messaging .handler .annotation .support .MessageHandlerMethodFactory ;
95
- import org .springframework .messaging .handler .annotation .support .MethodArgumentNotValidException ;
96
- import org .springframework .messaging .handler .annotation .support .PayloadMethodArgumentResolver ;
97
91
import org .springframework .messaging .handler .invocation .HandlerMethodArgumentResolver ;
98
92
import org .springframework .messaging .handler .invocation .InvocableHandlerMethod ;
99
93
import org .springframework .util .Assert ;
100
94
import org .springframework .util .ClassUtils ;
101
95
import org .springframework .util .CollectionUtils ;
102
96
import org .springframework .util .ReflectionUtils ;
103
97
import org .springframework .util .StringUtils ;
104
- import org .springframework .validation .BindingResult ;
105
- import org .springframework .validation .ObjectError ;
106
98
import org .springframework .validation .Validator ;
107
99
108
100
/**
@@ -440,14 +432,10 @@ protected Collection<Declarable> processListener(MethodRabbitListenerEndpoint en
440
432
List <Object > resolvedQueues = resolveQueues (rabbitListener , declarables );
441
433
if (!resolvedQueues .isEmpty ()) {
442
434
if (resolvedQueues .get (0 ) instanceof String ) {
443
- endpoint .setQueueNames (resolvedQueues .stream ()
444
- .map (o -> (String ) o )
445
- .collect (Collectors .toList ()).toArray (new String [0 ]));
435
+ endpoint .setQueueNames (resolvedQueues .stream ().map (o -> (String ) o ).toArray (String []::new ));
446
436
}
447
437
else {
448
- endpoint .setQueues (resolvedQueues .stream ()
449
- .map (o -> (Queue ) o )
450
- .collect (Collectors .toList ()).toArray (new Queue [0 ]));
438
+ endpoint .setQueues (resolvedQueues .stream ().map (o -> (Queue ) o ).toArray (Queue []::new ));
451
439
}
452
440
}
453
441
endpoint .setConcurrency (resolveExpressionAsStringOrInteger (rabbitListener .concurrency (), "concurrency" ));
@@ -664,12 +652,10 @@ private List<Object> resolveQueues(RabbitListener rabbitListener, Collection<Dec
664
652
String [] queues = rabbitListener .queues ();
665
653
QueueBinding [] bindings = rabbitListener .bindings ();
666
654
org .springframework .amqp .rabbit .annotation .Queue [] queuesToDeclare = rabbitListener .queuesToDeclare ();
667
- List <String > queueNames = new ArrayList <String >();
668
- List <Queue > queueBeans = new ArrayList <Queue >();
669
- if (queues .length > 0 ) {
670
- for (int i = 0 ; i < queues .length ; i ++) {
671
- resolveQueues (queues [i ], queueNames , queueBeans );
672
- }
655
+ List <String > queueNames = new ArrayList <>();
656
+ List <Queue > queueBeans = new ArrayList <>();
657
+ for (String queue : queues ) {
658
+ resolveQueues (queue , queueNames , queueBeans );
673
659
}
674
660
if (!queueNames .isEmpty ()) {
675
661
// revert to the previous behavior of just using the name when there is mixture of String and Queue
@@ -681,8 +667,8 @@ private List<Object> resolveQueues(RabbitListener rabbitListener, Collection<Dec
681
667
throw new BeanInitializationException (
682
668
"@RabbitListener can have only one of 'queues', 'queuesToDeclare', or 'bindings'" );
683
669
}
684
- for (int i = 0 ; i < queuesToDeclare . length ; i ++ ) {
685
- queueNames .add (declareQueue (queuesToDeclare [ i ] , declarables ));
670
+ for (org . springframework . amqp . rabbit . annotation . Queue queue : queuesToDeclare ) {
671
+ queueNames .add (declareQueue (queue , declarables ));
686
672
}
687
673
}
688
674
if (bindings .length > 0 ) {
@@ -752,7 +738,7 @@ private String[] registerBeansForDeclaration(RabbitListener rabbitListener, Coll
752
738
declareExchangeAndBinding (binding , queueName , declarables );
753
739
}
754
740
}
755
- return queues .toArray (new String [queues . size () ]);
741
+ return queues .toArray (new String [0 ]);
756
742
}
757
743
758
744
private String declareQueue (org .springframework .amqp .rabbit .annotation .Queue bindingQueue ,
@@ -859,7 +845,7 @@ private void registerBindings(QueueBinding binding, String queueName, String exc
859
845
}
860
846
861
847
private Map <String , Object > resolveArguments (Argument [] arguments ) {
862
- Map <String , Object > map = new HashMap <String , Object >();
848
+ Map <String , Object > map = new HashMap <>();
863
849
for (Argument arg : arguments ) {
864
850
String key = resolveExpressionAsString (arg .name (), "@Argument.name" );
865
851
if (StringUtils .hasText (key )) {
@@ -1025,7 +1011,7 @@ private MessageHandlerMethodFactory getFactory() {
1025
1011
}
1026
1012
1027
1013
private MessageHandlerMethodFactory createDefaultMessageHandlerMethodFactory () {
1028
- DefaultMessageHandlerMethodFactory defaultFactory = new DefaultMessageHandlerMethodFactory ();
1014
+ DefaultMessageHandlerMethodFactory defaultFactory = new AmqpMessageHandlerMethodFactory ();
1029
1015
Validator validator = RabbitListenerAnnotationBeanPostProcessor .this .registrar .getValidator ();
1030
1016
if (validator != null ) {
1031
1017
defaultFactory .setValidator (validator );
@@ -1038,74 +1024,14 @@ private MessageHandlerMethodFactory createDefaultMessageHandlerMethodFactory() {
1038
1024
List <HandlerMethodArgumentResolver > customArgumentsResolver = new ArrayList <>(
1039
1025
RabbitListenerAnnotationBeanPostProcessor .this .registrar .getCustomMethodArgumentResolvers ());
1040
1026
defaultFactory .setCustomArgumentResolvers (customArgumentsResolver );
1041
- GenericMessageConverter messageConverter = new GenericMessageConverter (
1042
- this .defaultFormattingConversionService );
1043
- defaultFactory .setMessageConverter (messageConverter );
1044
- // Has to be at the end - look at PayloadMethodArgumentResolver documentation
1045
- customArgumentsResolver .add (new OptionalEmptyAwarePayloadArgumentResolver (messageConverter , validator ));
1027
+ defaultFactory .setMessageConverter (new GenericMessageConverter (this .defaultFormattingConversionService ));
1028
+
1046
1029
defaultFactory .afterPropertiesSet ();
1047
1030
return defaultFactory ;
1048
1031
}
1049
1032
1050
1033
}
1051
1034
1052
- private static class OptionalEmptyAwarePayloadArgumentResolver extends PayloadMethodArgumentResolver {
1053
-
1054
- OptionalEmptyAwarePayloadArgumentResolver (
1055
- org .springframework .messaging .converter .MessageConverter messageConverter ,
1056
- @ Nullable Validator validator ) {
1057
-
1058
- super (messageConverter , validator );
1059
- }
1060
-
1061
- @ Override
1062
- public Object resolveArgument (MethodParameter parameter , Message <?> message ) throws Exception { // NOSONAR
1063
- Object resolved = null ;
1064
- try {
1065
- resolved = super .resolveArgument (parameter , message );
1066
- }
1067
- catch (MethodArgumentNotValidException ex ) {
1068
- Type type = parameter .getGenericParameterType ();
1069
- if (isOptional (message , type )) {
1070
- BindingResult bindingResult = ex .getBindingResult ();
1071
- if (bindingResult != null ) {
1072
- List <ObjectError > allErrors = bindingResult .getAllErrors ();
1073
- if (allErrors .size () == 1 ) {
1074
- String defaultMessage = allErrors .get (0 ).getDefaultMessage ();
1075
- if ("Payload value must not be empty" .equals (defaultMessage )) {
1076
- return Optional .empty ();
1077
- }
1078
- }
1079
- }
1080
- }
1081
- throw ex ;
1082
- }
1083
- /*
1084
- * Replace Optional.empty() list elements with null.
1085
- */
1086
- if (resolved instanceof List ) {
1087
- List <?> list = ((List <?>) resolved );
1088
- for (int i = 0 ; i < list .size (); i ++) {
1089
- if (list .get (i ).equals (Optional .empty ())) {
1090
- list .set (i , null );
1091
- }
1092
- }
1093
- }
1094
- return resolved ;
1095
- }
1096
-
1097
- private boolean isOptional (Message <?> message , Type type ) {
1098
- return (Optional .class .equals (type ) || (type instanceof ParameterizedType
1099
- && Optional .class .equals (((ParameterizedType ) type ).getRawType ())))
1100
- && message .getPayload ().equals (Optional .empty ());
1101
- }
1102
-
1103
- @ Override
1104
- protected boolean isEmptyPayload (Object payload ) {
1105
- return payload == null || payload .equals (Optional .empty ());
1106
- }
1107
-
1108
- }
1109
1035
/**
1110
1036
* The metadata holder of the class with {@link RabbitListener}
1111
1037
* and {@link RabbitHandler} annotations.
@@ -1145,6 +1071,9 @@ private TypeMetadata() {
1145
1071
1146
1072
/**
1147
1073
* A method annotated with {@link RabbitListener}, together with the annotations.
1074
+ *
1075
+ * @param method the method with annotations
1076
+ * @param annotations on the method
1148
1077
*/
1149
1078
private static class ListenerMethod {
1150
1079
0 commit comments