15
15
*/
16
16
package org .springframework .modulith .events .support ;
17
17
18
+ import java .lang .reflect .Method ;
18
19
import java .time .Duration ;
19
20
import java .util .Collection ;
20
21
import java .util .List ;
45
46
import org .springframework .transaction .event .TransactionPhase ;
46
47
import org .springframework .transaction .event .TransactionalApplicationListener ;
47
48
import org .springframework .util .Assert ;
49
+ import org .springframework .util .ReflectionUtils ;
48
50
49
51
/**
50
52
* An {@link org.springframework.context.event.ApplicationEventMulticaster} to register {@link EventPublication}s in an
@@ -61,12 +63,23 @@ public class PersistentApplicationEventMulticaster extends AbstractApplicationEv
61
63
implements IncompleteEventPublications , SmartInitializingSingleton {
62
64
63
65
private static final Logger LOGGER = LoggerFactory .getLogger (PersistentApplicationEventMulticaster .class );
66
+ private static final Method LEGACY_SHOULD_HANDLE = ReflectionUtils .findMethod (ApplicationListenerMethodAdapter .class ,
67
+ "shouldHandle" , ApplicationEvent .class , Object [].class );
68
+ private static final Method SHOULD_HANDLE = ReflectionUtils .findMethod (ApplicationListenerMethodAdapter .class ,
69
+ "shouldHandle" , ApplicationEvent .class );
64
70
65
71
static final String REPUBLISH_ON_RESTART = "spring.modulith.republish-outstanding-events-on-restart" ;
66
72
67
73
private final @ NonNull Supplier <EventPublicationRegistry > registry ;
68
74
private final @ NonNull Supplier <Environment > environment ;
69
75
76
+ static {
77
+
78
+ if (SHOULD_HANDLE == null ) {
79
+ ReflectionUtils .makeAccessible (LEGACY_SHOULD_HANDLE );
80
+ }
81
+ }
82
+
70
83
/**
71
84
* Creates a new {@link PersistentApplicationEventMulticaster} for the given {@link EventPublicationRegistry}.
72
85
*
@@ -222,9 +235,7 @@ private static Object getEventToPersist(ApplicationEvent event) {
222
235
private static boolean matches (ApplicationEvent event , Object payload , ApplicationListener <?> listener ) {
223
236
224
237
// Verify general listener matching by eagerly evaluating the condition
225
- if (ApplicationListenerMethodAdapter .class .isInstance (listener )
226
- && !((ApplicationListenerMethodAdapter ) listener ).shouldHandle (event )) {
227
-
238
+ if (!invokeShouldHandle (listener , event , payload )) {
228
239
return false ;
229
240
}
230
241
@@ -233,6 +244,27 @@ private static boolean matches(ApplicationEvent event, Object payload, Applicati
233
244
: true ;
234
245
}
235
246
247
+ /**
248
+ * Invokes {@link ApplicationListenerMethodAdapter#shouldHandle(ApplicationEvent)} in case the given candidate is one
249
+ * in the first place but falls back to call {@code shouldHandle(ApplicationEvent, Object)} reflectively as fallback.
250
+ *
251
+ * @param candidate the listener to test, must not be {@literal null}.
252
+ * @param event the event to publish, must not be {@literal null}.
253
+ * @param payload the actual payload, must not be {@literal null}.
254
+ * @return whether the event should be handled by the given candidate.
255
+ */
256
+ @ SuppressWarnings ("null" )
257
+ private static boolean invokeShouldHandle (ApplicationListener <?> candidate , ApplicationEvent event , Object payload ) {
258
+
259
+ if (!(candidate instanceof ApplicationListenerMethodAdapter listener )) {
260
+ return true ;
261
+ }
262
+
263
+ return SHOULD_HANDLE != null
264
+ ? listener .shouldHandle (event )
265
+ : (boolean ) ReflectionUtils .invokeMethod (LEGACY_SHOULD_HANDLE , candidate , event , new Object [] { payload });
266
+ }
267
+
236
268
private static String getConfirmationMessage (Collection <?> publications ) {
237
269
238
270
var size = publications .size ();
0 commit comments