diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index a2068695e0e..de9e8c4b8c2 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -369,7 +369,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader else { applicationEvent = new PayloadApplicationEvent(this, event); if (eventType == null) { - eventType = ResolvableType.forClassWithGenerics(PayloadApplicationEvent.class, event.getClass()); + eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType(); } } diff --git a/spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java b/spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java index 18a9a97cbb0..705517e5a9f 100644 --- a/spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java +++ b/spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,6 +50,7 @@ import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.context.event.test.AbstractIdentifiable; import org.springframework.context.event.test.AnotherTestEvent; import org.springframework.context.event.test.EventCollector; +import org.springframework.context.event.test.GenericEventPojo; import org.springframework.context.event.test.Identifiable; import org.springframework.context.event.test.TestEvent; import org.springframework.context.support.ClassPathXmlApplicationContext; @@ -454,6 +455,30 @@ public class AnnotationDrivenEventListenerTests { this.eventCollector.assertTotalEventsCount(1); } + @Test + public void listenerWithResolvableTypeEvent() { + load(ResolvableTypeEventListener.class); + ResolvableTypeEventListener listener = this.context.getBean(ResolvableTypeEventListener.class); + + this.eventCollector.assertNoEventReceived(listener); + GenericEventPojo event = new GenericEventPojo<>("TEST"); + this.context.publishEvent(event); + this.eventCollector.assertEvent(listener, event); + this.eventCollector.assertTotalEventsCount(1); + } + + @Test + public void listenerWithResolvableTypeEventWrongGeneric() { + load(ResolvableTypeEventListener.class); + ResolvableTypeEventListener listener = this.context.getBean(ResolvableTypeEventListener.class); + + this.eventCollector.assertNoEventReceived(listener); + GenericEventPojo event = new GenericEventPojo<>(123L); + this.context.publishEvent(event); + this.eventCollector.assertNoEventReceived(listener); + this.eventCollector.assertTotalEventsCount(0); + } + @Test public void conditionMatch() { long timestamp = System.currentTimeMillis(); @@ -833,6 +858,16 @@ public class AnnotationDrivenEventListenerTests { } + @Component + static class ResolvableTypeEventListener extends AbstractTestEventListener { + + @EventListener + public void handleString(GenericEventPojo value) { + collectEvent(value); + } + } + + @Component static class ConditionalEventListener extends TestEventListener { diff --git a/spring-context/src/test/java/org/springframework/context/event/test/GenericEventPojo.java b/spring-context/src/test/java/org/springframework/context/event/test/GenericEventPojo.java new file mode 100644 index 00000000000..532f08ae015 --- /dev/null +++ b/spring-context/src/test/java/org/springframework/context/event/test/GenericEventPojo.java @@ -0,0 +1,53 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.event.test; + +import org.springframework.core.ResolvableType; +import org.springframework.core.ResolvableTypeProvider; + +/** + * A simple POJO that implements {@link ResolvableTypeProvider}. + * + * @author Stephane Nicoll + */ +public class GenericEventPojo implements ResolvableTypeProvider { + private final T value; + + public GenericEventPojo(T value) { + this.value = value; + } + + @Override + public ResolvableType getResolvableType() { + return ResolvableType.forClassWithGenerics(getClass(), ResolvableType.forInstance(this.value)); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + GenericEventPojo that = (GenericEventPojo) o; + + return this.value.equals(that.value); + } + + @Override + public int hashCode() { + return this.value.hashCode(); + } +}