ResolvableType-based matching respects generic factory method return type
Includes consistent use of ResolvableType.resolve() wherever applicable. Issue: SPR-15011
This commit is contained in:
@@ -343,17 +343,15 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
|
||||
ResolvableType payloadType = null;
|
||||
if (event instanceof PayloadApplicationEvent) {
|
||||
PayloadApplicationEvent<?> payloadEvent = (PayloadApplicationEvent<?>) event;
|
||||
payloadType = payloadEvent.getResolvableType().as(
|
||||
PayloadApplicationEvent.class).getGeneric(0);
|
||||
payloadType = payloadEvent.getResolvableType().as(PayloadApplicationEvent.class).getGeneric();
|
||||
}
|
||||
for (ResolvableType declaredEventType : this.declaredEventTypes) {
|
||||
if (!ApplicationEvent.class.isAssignableFrom(declaredEventType.getRawClass())
|
||||
&& payloadType != null) {
|
||||
if (!ApplicationEvent.class.isAssignableFrom(declaredEventType.getRawClass()) && payloadType != null) {
|
||||
if (declaredEventType.isAssignableFrom(payloadType)) {
|
||||
return declaredEventType;
|
||||
}
|
||||
}
|
||||
if (declaredEventType.getRawClass().isAssignableFrom(event.getClass())) {
|
||||
if (declaredEventType.getRawClass().isInstance(event)) {
|
||||
return declaredEventType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -60,8 +60,8 @@ public class GenericApplicationListenerAdapter implements GenericApplicationList
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean supportsEventType(ResolvableType eventType) {
|
||||
if (this.delegate instanceof SmartApplicationListener) {
|
||||
Class<? extends ApplicationEvent> eventClass = (Class<? extends ApplicationEvent>) eventType.getRawClass();
|
||||
return ((SmartApplicationListener) this.delegate).supportsEventType(eventClass);
|
||||
Class<? extends ApplicationEvent> eventClass = (Class<? extends ApplicationEvent>) eventType.resolve();
|
||||
return (eventClass != null && ((SmartApplicationListener) this.delegate).supportsEventType(eventClass));
|
||||
}
|
||||
else {
|
||||
return (this.declaredEventType == null || this.declaredEventType.isAssignableFrom(eventType));
|
||||
@@ -70,7 +70,7 @@ public class GenericApplicationListenerAdapter implements GenericApplicationList
|
||||
|
||||
@Override
|
||||
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
|
||||
return supportsEventType(ResolvableType.forType(eventType));
|
||||
return supportsEventType(ResolvableType.forClass(eventType));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.componentscan.simple.SimpleComponent;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.io.DescriptiveResource;
|
||||
@@ -50,6 +51,7 @@ import org.springframework.stereotype.Component;
|
||||
import org.springframework.tests.sample.beans.ITestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@@ -522,6 +524,33 @@ public class ConfigurationClassPostProcessorTests {
|
||||
assertSame(beanFactory.getBean("genericRepo"), beanFactory.getBean("repoConsumer"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void genericsBasedInjectionWithLateGenericsMatching() {
|
||||
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RepositoryConfiguration.class));
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
beanFactory.preInstantiateSingletons();
|
||||
|
||||
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
|
||||
assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo"));
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void genericsBasedInjectionWithEarlyGenericsMatching() {
|
||||
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RepositoryConfiguration.class));
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
|
||||
String[] beanNames = beanFactory.getBeanNamesForType(Repository.class);
|
||||
assertTrue(ObjectUtils.containsElement(beanNames, "stringRepo"));
|
||||
|
||||
beanNames = beanFactory.getBeanNamesForType(ResolvableType.forClassWithGenerics(Repository.class, String.class));
|
||||
assertEquals(1, beanNames.length);
|
||||
assertEquals("stringRepo", beanNames[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelfReferenceExclusionForFactoryMethodOnSameBean() {
|
||||
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
|
||||
|
||||
Reference in New Issue
Block a user