Resolve ApplicationListener against BeanDefinition.getResolvableType()
This covers ApplicationListener generics in factory method return types in particular but also allows for programmatic setTargetType hints. Closes gh-23178
This commit is contained in:
@@ -19,6 +19,7 @@ package org.springframework.beans.factory.config;
|
||||
import org.springframework.beans.BeanMetadataElement;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.core.AttributeAccessor;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
@@ -304,6 +305,17 @@ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
|
||||
|
||||
// Read-only attributes
|
||||
|
||||
/**
|
||||
* Return a resolvable type for this bean definition,
|
||||
* based on the bean class or other specific metadata.
|
||||
* <p>This is typically fully resolved on a runtime-merged bean definition
|
||||
* but not necessarily on a configuration-time definition instance.
|
||||
* @return the resolvable type (potentially {@link ResolvableType#NONE})
|
||||
* @since 5.2
|
||||
* @see ConfigurableBeanFactory#getMergedBeanDefinition
|
||||
*/
|
||||
ResolvableType getResolvableType();
|
||||
|
||||
/**
|
||||
* Return whether this a <b>Singleton</b>, with a single, shared instance
|
||||
* returned on all calls.
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.io.DescriptiveResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -458,6 +459,16 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
|
||||
return resolvedClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a resolvable type for this bean definition.
|
||||
* <p>This implementation delegates to {@link #getBeanClass()}.
|
||||
* @since 5.2
|
||||
*/
|
||||
@Override
|
||||
public ResolvableType getResolvableType() {
|
||||
return (hasBeanClass() ? ResolvableType.forClass(getBeanClass()) : ResolvableType.NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the target scope for the bean.
|
||||
* <p>The default is singleton status, although this is only applied once
|
||||
|
||||
@@ -331,14 +331,28 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
/**
|
||||
* Return a {@link ResolvableType} for this bean definition,
|
||||
* either from runtime-cached type information or from configuration-time
|
||||
* {@link #setTargetType(ResolvableType)} or {@link #setBeanClass(Class)}.
|
||||
* {@link #setTargetType(ResolvableType)} or {@link #setBeanClass(Class)},
|
||||
* also considering resolved factory method definitions.
|
||||
* @since 5.1
|
||||
* @see #getTargetType()
|
||||
* @see #getBeanClass()
|
||||
* @see #setTargetType(ResolvableType)
|
||||
* @see #setBeanClass(Class)
|
||||
* @see #setResolvedFactoryMethod(Method)
|
||||
*/
|
||||
@Override
|
||||
public ResolvableType getResolvableType() {
|
||||
ResolvableType targetType = this.targetType;
|
||||
return (targetType != null ? targetType : ResolvableType.forClass(getBeanClass()));
|
||||
if (targetType != null) {
|
||||
return targetType;
|
||||
}
|
||||
ResolvableType returnType = this.factoryMethodReturnType;
|
||||
if (returnType != null) {
|
||||
return returnType;
|
||||
}
|
||||
Method factoryMethod = this.factoryMethodToIntrospect;
|
||||
if (factoryMethod != null) {
|
||||
return ResolvableType.forMethodReturnType(factoryMethod);
|
||||
}
|
||||
return super.getResolvableType();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user