Add support for target type to BeanRegistry

Closes gh-34560
This commit is contained in:
Sébastien Deleuze
2025-03-10 10:14:28 +01:00
parent c74f897fac
commit a0e2d3a221
8 changed files with 173 additions and 1 deletions

View File

@@ -24,6 +24,8 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.ResolvableType;
import org.springframework.core.env.Environment;
@@ -149,6 +151,20 @@ public interface BeanRegistry {
* @see AbstractBeanDefinition#setInstanceSupplier(Supplier)
*/
Spec<T> supplier(Function<SupplierContext, T> supplier);
/**
* Set a generics-containing target type of this bean.
* @see #targetType(ResolvableType)
* @see RootBeanDefinition#setTargetType(ResolvableType)
*/
Spec<T> targetType(ParameterizedTypeReference<? extends T> type);
/**
* Set a generics-containing target type of this bean.
* @see #targetType(ParameterizedTypeReference)
* @see RootBeanDefinition#setTargetType(ResolvableType)
*/
Spec<T> targetType(ResolvableType type);
}
/**

View File

@@ -30,6 +30,7 @@ import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionCustomizer;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.ResolvableType;
import org.springframework.util.MultiValueMap;
@@ -211,6 +212,18 @@ public class BeanRegistryAdapter implements BeanRegistry {
supplier.apply(new SupplierContextAdapter(this.beanFactory)));
return this;
}
@Override
public Spec<T> targetType(ParameterizedTypeReference<? extends T> targetType) {
this.beanDefinition.setTargetType(ResolvableType.forType(targetType));
return this;
}
@Override
public Spec<T> targetType(ResolvableType targetType) {
this.beanDefinition.setTargetType(targetType);
return this;
}
}
static class SupplierContextAdapter implements SupplierContext {

View File

@@ -122,6 +122,10 @@ open class BeanRegistrarDsl(private val init: BeanRegistrarDsl.() -> Unit): Bean
if (prototype) {
it.prototype()
}
val resolvableType = ResolvableType.forType(object: ParameterizedTypeReference<T>() {});
if (resolvableType.hasGenerics()) {
it.targetType(resolvableType)
}
}
registry.registerBean(name, T::class.java, customizer)
}
@@ -184,6 +188,10 @@ open class BeanRegistrarDsl(private val init: BeanRegistrarDsl.() -> Unit): Bean
if (prototype) {
it.prototype()
}
val resolvableType = ResolvableType.forType(object: ParameterizedTypeReference<T>() {});
if (resolvableType.hasGenerics()) {
it.targetType(resolvableType)
}
}
return registry.registerBean(T::class.java, customizer)
}
@@ -250,6 +258,10 @@ open class BeanRegistrarDsl(private val init: BeanRegistrarDsl.() -> Unit): Bean
it.supplier {
SupplierContextDsl<T>(it).supplier()
}
val resolvableType = ResolvableType.forType(object: ParameterizedTypeReference<T>() {});
if (resolvableType.hasGenerics()) {
it.targetType(resolvableType)
}
}
registry.registerBean(name, T::class.java, customizer)
}
@@ -314,6 +326,10 @@ open class BeanRegistrarDsl(private val init: BeanRegistrarDsl.() -> Unit): Bean
it.supplier {
SupplierContextDsl<T>(it).supplier()
}
val resolvableType = ResolvableType.forType(object: ParameterizedTypeReference<T>() {});
if (resolvableType.hasGenerics()) {
it.targetType(resolvableType)
}
}
return registry.registerBean(T::class.java, customizer)
}