Skip to content

Commit 8ad3c95

Browse files
committed
Reliably detect event listener conditions on proxied beans
Issue: SPR-15678 (cherry picked from commit eb928ce)
1 parent 8d74318 commit 8ad3c95

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -37,6 +37,7 @@
3737
import org.springframework.core.annotation.Order;
3838
import org.springframework.expression.EvaluationContext;
3939
import org.springframework.util.Assert;
40+
import org.springframework.util.ClassUtils;
4041
import org.springframework.util.ObjectUtils;
4142
import org.springframework.util.ReflectionUtils;
4243
import org.springframework.util.StringUtils;
@@ -87,7 +88,9 @@ public ApplicationListenerMethodAdapter(String beanName, Class<?> targetClass, M
8788
this.targetClass = targetClass;
8889
this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
8990

90-
EventListener ann = AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class);
91+
Method targetMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
92+
EventListener ann = AnnotatedElementUtils.findMergedAnnotation(targetMethod, EventListener.class);
93+
9194
this.declaredEventTypes = resolveDeclaredEventTypes(method, ann);
9295
this.condition = (ann != null ? ann.condition() : null);
9396
this.order = resolveOrder(method);
@@ -224,7 +227,7 @@ else if (result instanceof Collection<?>) {
224227

225228
private void publishEvent(Object event) {
226229
if (event != null) {
227-
Assert.notNull(this.applicationContext, "ApplicationContext must no be null");
230+
Assert.notNull(this.applicationContext, "ApplicationContext must not be null");
228231
this.applicationContext.publishEvent(event);
229232
}
230233
}

spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@
6060
import org.springframework.scheduling.annotation.EnableAsync;
6161
import org.springframework.stereotype.Component;
6262
import org.springframework.util.Assert;
63+
import org.springframework.validation.annotation.Validated;
64+
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
6365

6466
import static org.hamcrest.Matchers.*;
6567
import static org.junit.Assert.*;
@@ -488,10 +490,20 @@ public void listenerWithResolvableTypeEventWrongGeneric() {
488490

489491
@Test
490492
public void conditionMatch() {
493+
validateConditionMatch(ConditionalEventListener.class);
494+
}
495+
496+
@Test
497+
public void conditionMatchWithProxy() {
498+
validateConditionMatch(ConditionalEventListener.class, MethodValidationPostProcessor.class);
499+
}
500+
501+
private void validateConditionMatch(Class<?>... classes) {
491502
long timestamp = System.currentTimeMillis();
492-
load(ConditionalEventListener.class);
503+
load(classes);
493504
TestEvent event = new TestEvent(this, "OK");
494-
TestEventListener listener = this.context.getBean(ConditionalEventListener.class);
505+
506+
ConditionalEventInterface listener = this.context.getBean(ConditionalEventInterface.class);
495507
this.eventCollector.assertNoEventReceived(listener);
496508

497509
this.context.publishEvent(event);
@@ -502,6 +514,9 @@ public void conditionMatch() {
502514
this.eventCollector.assertEvent(listener, event, "OK");
503515
this.eventCollector.assertTotalEventsCount(2);
504516

517+
this.context.publishEvent("NOT OK");
518+
this.eventCollector.assertTotalEventsCount(2);
519+
505520
this.context.publishEvent(timestamp);
506521
this.eventCollector.assertEvent(listener, event, "OK", timestamp);
507522
this.eventCollector.assertTotalEventsCount(3);
@@ -885,8 +900,21 @@ public void handleString(GenericEventPojo<String> value) {
885900
}
886901

887902

903+
interface ConditionalEventInterface extends Identifiable {
904+
905+
void handle(TestEvent event);
906+
907+
void handleString(String payload);
908+
909+
void handleTimestamp(Long timestamp);
910+
911+
void handleRatio(Double ratio);
912+
}
913+
914+
888915
@Component
889-
static class ConditionalEventListener extends TestEventListener {
916+
@Validated
917+
static class ConditionalEventListener extends TestEventListener implements ConditionalEventInterface {
890918

891919
@EventListener(condition = "'OK'.equals(#root.event.msg)")
892920
@Override

0 commit comments

Comments
 (0)