1
1
/*
2
- * Copyright 2002-2020 the original author or authors.
2
+ * Copyright 2002-2023 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.
19
19
import java .io .IOException ;
20
20
import java .lang .reflect .Method ;
21
21
import java .lang .reflect .UndeclaredThrowableException ;
22
+ import java .util .List ;
22
23
23
24
import org .junit .jupiter .api .Test ;
24
25
46
47
47
48
/**
48
49
* @author Stephane Nicoll
50
+ * @author Juergen Hoeller
51
+ * @author Simon Baslé
49
52
*/
50
53
public class ApplicationListenerMethodAdapterTests extends AbstractApplicationEventListenerTests {
51
54
@@ -80,16 +83,23 @@ public void genericListenerWrongParameterizedType() {
80
83
supportsEventType (false , method , ResolvableType .forClassWithGenerics (GenericTestEvent .class , Long .class ));
81
84
}
82
85
86
+ @ Test
87
+ public void genericListenerWithUnresolvedGenerics () {
88
+ Method method = ReflectionUtils .findMethod (
89
+ SampleEvents .class , "handleGenericString" , GenericTestEvent .class );
90
+ supportsEventType (true , method , ResolvableType .forClass (GenericTestEvent .class ));
91
+ }
92
+
83
93
@ Test
84
94
public void listenerWithPayloadAndGenericInformation () {
85
95
Method method = ReflectionUtils .findMethod (SampleEvents .class , "handleString" , String .class );
86
- supportsEventType (true , method , createGenericEventType (String .class ));
96
+ supportsEventType (true , method , createPayloadEventType (String .class ));
87
97
}
88
98
89
99
@ Test
90
100
public void listenerWithInvalidPayloadAndGenericInformation () {
91
101
Method method = ReflectionUtils .findMethod (SampleEvents .class , "handleString" , String .class );
92
- supportsEventType (false , method , createGenericEventType (Integer .class ));
102
+ supportsEventType (false , method , createPayloadEventType (Integer .class ));
93
103
}
94
104
95
105
@ Test
@@ -113,28 +123,28 @@ public void listenerWithSubTypeSeveralGenericsResolved() {
113
123
@ Test
114
124
public void listenerWithAnnotationValue () {
115
125
Method method = ReflectionUtils .findMethod (SampleEvents .class , "handleStringAnnotationValue" );
116
- supportsEventType (true , method , createGenericEventType (String .class ));
126
+ supportsEventType (true , method , createPayloadEventType (String .class ));
117
127
}
118
128
119
129
@ Test
120
130
public void listenerWithAnnotationClasses () {
121
131
Method method = ReflectionUtils .findMethod (SampleEvents .class , "handleStringAnnotationClasses" );
122
- supportsEventType (true , method , createGenericEventType (String .class ));
132
+ supportsEventType (true , method , createPayloadEventType (String .class ));
123
133
}
124
134
125
135
@ Test
126
136
public void listenerWithAnnotationValueAndParameter () {
127
137
Method method = ReflectionUtils .findMethod (
128
138
SampleEvents .class , "handleStringAnnotationValueAndParameter" , String .class );
129
- supportsEventType (true , method , createGenericEventType (String .class ));
139
+ supportsEventType (true , method , createPayloadEventType (String .class ));
130
140
}
131
141
132
142
@ Test
133
143
public void listenerWithSeveralTypes () {
134
144
Method method = ReflectionUtils .findMethod (SampleEvents .class , "handleStringOrInteger" );
135
- supportsEventType (true , method , createGenericEventType (String .class ));
136
- supportsEventType (true , method , createGenericEventType (Integer .class ));
137
- supportsEventType (false , method , createGenericEventType (Double .class ));
145
+ supportsEventType (true , method , createPayloadEventType (String .class ));
146
+ supportsEventType (true , method , createPayloadEventType (Integer .class ));
147
+ supportsEventType (false , method , createPayloadEventType (Double .class ));
138
148
}
139
149
140
150
@ Test
@@ -325,6 +335,88 @@ public void beanInstanceRetrievedAtEveryInvocation() {
325
335
verify (this .context , times (2 )).getBean ("testBean" );
326
336
}
327
337
338
+ @ Test // gh-30399
339
+ void simplePayloadDoesNotSupportArbitraryGenericEventType () throws Exception {
340
+ Method method = SampleEvents .class .getDeclaredMethod ("handleString" , String .class );
341
+ ApplicationListenerMethodAdapter adapter = createTestInstance (method );
342
+
343
+ assertThat (adapter .supportsEventType (createPayloadEventType (ResolvableType .forClassWithGenerics (EntityWrapper .class , Integer .class ))))
344
+ .as ("handleString(String) with EntityWrapper<Integer>" ).isFalse ();
345
+ assertThat (adapter .supportsEventType (createPayloadEventType (ResolvableType .forClass (EntityWrapper .class ))))
346
+ .as ("handleString(String) with EntityWrapper<?>" ).isFalse ();
347
+ assertThat (adapter .supportsEventType (createPayloadEventType (ResolvableType .forClass (String .class ))))
348
+ .as ("handleString(String) with String" ).isTrue ();
349
+ }
350
+
351
+ @ Test // gh-30399
352
+ void genericPayloadDoesNotSupportArbitraryGenericEventType () throws Exception {
353
+ Method method = SampleEvents .class .getDeclaredMethod ("handleGenericStringPayload" , EntityWrapper .class );
354
+ ApplicationListenerMethodAdapter adapter = createTestInstance (method );
355
+
356
+ assertThat (adapter .supportsEventType (createPayloadEventType (ResolvableType .forClass (EntityWrapper .class ))))
357
+ .as ("handleGenericStringPayload(EntityWrapper<String>) with EntityWrapper<?>" ).isFalse ();
358
+ assertThat (adapter .supportsEventType (createPayloadEventType (ResolvableType .forClassWithGenerics (EntityWrapper .class , Integer .class ))))
359
+ .as ("handleGenericStringPayload(EntityWrapper<String>) with EntityWrapper<Integer>" ).isFalse ();
360
+ assertThat (adapter .supportsEventType (createPayloadEventType (ResolvableType .forClassWithGenerics (EntityWrapper .class , String .class ))))
361
+ .as ("handleGenericStringPayload(EntityWrapper<String>) with EntityWrapper<String>" ).isTrue ();
362
+ }
363
+
364
+ @ Test // gh-30399
365
+ void rawGenericPayloadDoesNotSupportArbitraryGenericEventType () throws Exception {
366
+ Method method = SampleEvents .class .getDeclaredMethod ("handleGenericAnyPayload" , EntityWrapper .class );
367
+ ApplicationListenerMethodAdapter adapter = createTestInstance (method );
368
+
369
+ assertThat (adapter .supportsEventType (createPayloadEventType (ResolvableType .forClass (EntityWrapper .class ))))
370
+ .as ("handleGenericAnyPayload(EntityWrapper<?>) with EntityWrapper<?>" ).isTrue ();
371
+ assertThat (adapter .supportsEventType (createPayloadEventType (ResolvableType .forClassWithGenerics (EntityWrapper .class , Integer .class ))))
372
+ .as ("handleGenericAnyPayload(EntityWrapper<?>) with EntityWrapper<Integer>" ).isTrue ();
373
+ assertThat (adapter .supportsEventType (createPayloadEventType (ResolvableType .forClassWithGenerics (EntityWrapper .class , String .class ))))
374
+ .as ("handleGenericAnyPayload(EntityWrapper<?>) with EntityWrapper<String>" ).isTrue ();
375
+ assertThat (adapter .supportsEventType (createPayloadEventType (ResolvableType .forClass (List .class ))))
376
+ .as ("handleGenericAnyPayload(EntityWrapper<?>) with List<?>" ).isFalse ();
377
+ assertThat (adapter .supportsEventType (createPayloadEventType (ResolvableType .forClassWithGenerics (List .class , String .class ))))
378
+ .as ("handleGenericAnyPayload(EntityWrapper<?>) with List<String>" ).isFalse ();
379
+ }
380
+
381
+ @ Test // gh-30399
382
+ void genericApplicationEventSupportsSpecificType () throws Exception {
383
+ Method method = SampleEvents .class .getDeclaredMethod ("handleGenericString" , GenericTestEvent .class );
384
+ ApplicationListenerMethodAdapter adapter = createTestInstance (method );
385
+
386
+ assertThat (adapter .supportsEventType (ResolvableType .forClass (GenericTestEvent .class )))
387
+ .as ("handleGenericString(GenericTestEvent<String>) with GenericTestEvent<?>" ).isTrue ();
388
+ assertThat (adapter .supportsEventType (ResolvableType .forClassWithGenerics (GenericTestEvent .class , Integer .class )))
389
+ .as ("handleGenericString(GenericTestEvent<String>) with GenericTestEvent<Integer>" ).isFalse ();
390
+ assertThat (adapter .supportsEventType (ResolvableType .forClassWithGenerics (GenericTestEvent .class , String .class )))
391
+ .as ("handleGenericString(GenericTestEvent<String>) with GenericTestEvent<String>" ).isTrue ();
392
+ }
393
+
394
+ @ Test // gh-30399
395
+ void genericRawApplicationEventSupportsRawTypeAndAnySpecificType () throws Exception {
396
+ Method method = SampleEvents .class .getDeclaredMethod ("handleGenericRaw" , GenericTestEvent .class );
397
+ ApplicationListenerMethodAdapter adapter = createTestInstance (method );
398
+
399
+ assertThat (adapter .supportsEventType (ResolvableType .forClass (GenericTestEvent .class )))
400
+ .as ("handleGenericRaw(GenericTestEvent<?>) with GenericTestEvent<?>" ).isTrue ();
401
+ assertThat (adapter .supportsEventType (ResolvableType .forClassWithGenerics (GenericTestEvent .class , String .class )))
402
+ .as ("handleGenericRaw(GenericTestEvent<?>) with GenericTestEvent<String>" ).isTrue ();
403
+ assertThat (adapter .supportsEventType (ResolvableType .forClassWithGenerics (GenericTestEvent .class , Integer .class )))
404
+ .as ("handleGenericRaw(GenericTestEvent<?>) with GenericTestEvent<Integer>" ).isTrue ();
405
+ }
406
+
407
+ @ Test // gh-30399
408
+ void unrelatedApplicationEventDoesNotSupportRawTypeOrAnySpecificType () throws Exception {
409
+ Method method = SampleEvents .class .getDeclaredMethod ("handleUnrelated" , ContextRefreshedEvent .class );
410
+ ApplicationListenerMethodAdapter adapter = createTestInstance (method );
411
+
412
+ assertThat (adapter .supportsEventType (ResolvableType .forClass (GenericTestEvent .class )))
413
+ .as ("handleUnrelated(ContextRefreshedEvent) with GenericTestEvent<?>" ).isTrue (); // known bug in 5.3.x
414
+ assertThat (adapter .supportsEventType (ResolvableType .forClassWithGenerics (GenericTestEvent .class , String .class )))
415
+ .as ("handleUnrelated(ContextRefreshedEvent) with GenericTestEvent<String>" ).isFalse ();
416
+ assertThat (adapter .supportsEventType (ResolvableType .forClassWithGenerics (GenericTestEvent .class , Integer .class )))
417
+ .as ("handleUnrelated(ContextRefreshedEvent) with GenericTestEvent<Integer>" ).isFalse ();
418
+ }
419
+
328
420
329
421
private void supportsEventType (boolean match , Method method , ResolvableType eventType ) {
330
422
ApplicationListenerMethodAdapter adapter = createTestInstance (method );
@@ -341,7 +433,11 @@ private ApplicationListenerMethodAdapter createTestInstance(Method method) {
341
433
return new StaticApplicationListenerMethodAdapter (method , this .sampleEvents );
342
434
}
343
435
344
- private ResolvableType createGenericEventType (Class <?> payloadType ) {
436
+ private ResolvableType createPayloadEventType (Class <?> payloadType ) {
437
+ return ResolvableType .forClassWithGenerics (PayloadApplicationEvent .class , payloadType );
438
+ }
439
+
440
+ private ResolvableType createPayloadEventType (ResolvableType payloadType ) {
345
441
return ResolvableType .forClassWithGenerics (PayloadApplicationEvent .class , payloadType );
346
442
}
347
443
@@ -373,6 +469,14 @@ public void handleRaw(ApplicationEvent event) {
373
469
public void handleGenericString (GenericTestEvent <String > event ) {
374
470
}
375
471
472
+ @ EventListener
473
+ public void handleGenericRaw (GenericTestEvent <?> event ) {
474
+ }
475
+
476
+ @ EventListener
477
+ public void handleUnrelated (ContextRefreshedEvent event ) {
478
+ }
479
+
376
480
@ EventListener
377
481
public void handleString (String payload ) {
378
482
}
0 commit comments