Generic bean type resolution for lookup methods

Closes gh-26998
This commit is contained in:
Juergen Hoeller
2021-05-28 17:23:52 +02:00
parent b18f8771c8
commit b3dcb64ff1
6 changed files with 102 additions and 23 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -35,6 +35,7 @@ import org.springframework.cglib.proxy.Factory;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -244,8 +245,10 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
return (bean.equals(null) ? null : bean);
}
else {
return (argsToUse != null ? this.owner.getBean(method.getReturnType(), argsToUse) :
this.owner.getBean(method.getReturnType()));
// Find target bean matching the (potentially generic) method return type
ResolvableType genericReturnType = ResolvableType.forMethodReturnType(method);
return (argsToUse != null ? this.owner.getBeanProvider(genericReturnType).getObject(argsToUse) :
this.owner.getBeanProvider(genericReturnType).getObject());
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2021 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.
@@ -19,17 +19,25 @@ package org.springframework.beans.factory.support;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
/**
* Represents an override of a method that looks up an object in the same IoC context.
* Represents an override of a method that looks up an object in the same IoC context,
* either by bean name or by bean type (based on the declared method return type).
*
* <p>Methods eligible for lookup override must not have arguments.
* <p>Methods eligible for lookup override may declare arguments in which case the
* given arguments are passed to the bean retrieval operation.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 1.1
* @see org.springframework.beans.factory.BeanFactory#getBean(String)
* @see org.springframework.beans.factory.BeanFactory#getBean(Class)
* @see org.springframework.beans.factory.BeanFactory#getBean(String, Object...)
* @see org.springframework.beans.factory.BeanFactory#getBean(Class, Object...)
* @see org.springframework.beans.factory.BeanFactory#getBeanProvider(ResolvableType)
*/
public class LookupOverride extends MethodOverride {
@@ -43,8 +51,8 @@ public class LookupOverride extends MethodOverride {
/**
* Construct a new LookupOverride.
* @param methodName the name of the method to override
* @param beanName the name of the bean in the current {@code BeanFactory}
* that the overridden method should return (may be {@code null})
* @param beanName the name of the bean in the current {@code BeanFactory} that the
* overridden method should return (may be {@code null} for type-based bean retrieval)
*/
public LookupOverride(String methodName, @Nullable String beanName) {
super(methodName);
@@ -53,9 +61,9 @@ public class LookupOverride extends MethodOverride {
/**
* Construct a new LookupOverride.
* @param method the method to override
* @param beanName the name of the bean in the current {@code BeanFactory}
* that the overridden method should return (may be {@code null})
* @param method the method declaration to override
* @param beanName the name of the bean in the current {@code BeanFactory} that the
* overridden method should return (may be {@code null} for type-based bean retrieval)
*/
public LookupOverride(Method method, @Nullable String beanName) {
super(method.getName());

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2021 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.
@@ -19,9 +19,8 @@ package org.springframework.beans.factory.support;
import java.lang.reflect.Method;
/**
* Interface to be implemented by classes that can reimplement any method
* on an IoC-managed object: the <b>Method Injection</b> form of
* Dependency Injection.
* Interface to be implemented by classes that can reimplement any method on an
* IoC-managed object: the <b>Method Injection</b> form of Dependency Injection.
*
* <p>Such methods may be (but need not be) abstract, in which case the
* container will create a concrete subclass to instantiate.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -25,7 +25,7 @@ import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* Extension of MethodOverride that represents an arbitrary
* Extension of {@link MethodOverride} that represents an arbitrary
* override of a method by the IoC container.
*
* <p>Any non-final method can be overridden, irrespective of its
@@ -45,7 +45,7 @@ public class ReplaceOverride extends MethodOverride {
/**
* Construct a new ReplaceOverride.
* @param methodName the name of the method to override
* @param methodReplacerBeanName the bean name of the MethodReplacer
* @param methodReplacerBeanName the bean name of the {@link MethodReplacer}
*/
public ReplaceOverride(String methodName, String methodReplacerBeanName) {
super(methodName);