|
|
|
@ -74,6 +74,7 @@ import org.springframework.core.GenericTypeResolver; |
|
|
|
import org.springframework.core.MethodParameter; |
|
|
|
import org.springframework.core.MethodParameter; |
|
|
|
import org.springframework.core.ParameterNameDiscoverer; |
|
|
|
import org.springframework.core.ParameterNameDiscoverer; |
|
|
|
import org.springframework.core.PriorityOrdered; |
|
|
|
import org.springframework.core.PriorityOrdered; |
|
|
|
|
|
|
|
import org.springframework.core.ResolvableType; |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
import org.springframework.util.ObjectUtils; |
|
|
|
import org.springframework.util.ObjectUtils; |
|
|
|
import org.springframework.util.ReflectionUtils; |
|
|
|
import org.springframework.util.ReflectionUtils; |
|
|
|
@ -672,9 +673,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac |
|
|
|
* @see #createBean |
|
|
|
* @see #createBean |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) { |
|
|
|
protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) { |
|
|
|
Class<?> preResolved = mbd.resolvedFactoryMethodReturnType; |
|
|
|
ResolvableType cachedReturnType = mbd.factoryMethodReturnType; |
|
|
|
if (preResolved != null) { |
|
|
|
if (cachedReturnType != null) { |
|
|
|
return preResolved; |
|
|
|
return cachedReturnType.resolve(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Class<?> factoryClass; |
|
|
|
Class<?> factoryClass; |
|
|
|
@ -698,11 +699,12 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac |
|
|
|
if (factoryClass == null) { |
|
|
|
if (factoryClass == null) { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
factoryClass = ClassUtils.getUserClass(factoryClass); |
|
|
|
|
|
|
|
|
|
|
|
// If all factory methods have the same return type, return that type.
|
|
|
|
// If all factory methods have the same return type, return that type.
|
|
|
|
// Can't clearly figure out exact method due to type converting / autowiring!
|
|
|
|
// Can't clearly figure out exact method due to type converting / autowiring!
|
|
|
|
Class<?> commonType = null; |
|
|
|
Class<?> commonType = null; |
|
|
|
boolean cache = false; |
|
|
|
Method uniqueCandidate = null; |
|
|
|
int minNrOfArgs = mbd.getConstructorArgumentValues().getArgumentCount(); |
|
|
|
int minNrOfArgs = mbd.getConstructorArgumentValues().getArgumentCount(); |
|
|
|
Method[] candidates = ReflectionUtils.getUniqueDeclaredMethods(factoryClass); |
|
|
|
Method[] candidates = ReflectionUtils.getUniqueDeclaredMethods(factoryClass); |
|
|
|
for (Method factoryMethod : candidates) { |
|
|
|
for (Method factoryMethod : candidates) { |
|
|
|
@ -736,8 +738,12 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac |
|
|
|
Class<?> returnType = AutowireUtils.resolveReturnTypeForFactoryMethod( |
|
|
|
Class<?> returnType = AutowireUtils.resolveReturnTypeForFactoryMethod( |
|
|
|
factoryMethod, args, getBeanClassLoader()); |
|
|
|
factoryMethod, args, getBeanClassLoader()); |
|
|
|
if (returnType != null) { |
|
|
|
if (returnType != null) { |
|
|
|
cache = true; |
|
|
|
uniqueCandidate = (commonType == null ? factoryMethod : null); |
|
|
|
commonType = ClassUtils.determineCommonAncestor(returnType, commonType); |
|
|
|
commonType = ClassUtils.determineCommonAncestor(returnType, commonType); |
|
|
|
|
|
|
|
if (commonType == null) { |
|
|
|
|
|
|
|
// Ambiguous return types found: return null to indicate "not determinable".
|
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Throwable ex) { |
|
|
|
catch (Throwable ex) { |
|
|
|
@ -747,22 +753,22 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
|
|
|
|
uniqueCandidate = (commonType == null ? factoryMethod : null); |
|
|
|
commonType = ClassUtils.determineCommonAncestor(factoryMethod.getReturnType(), commonType); |
|
|
|
commonType = ClassUtils.determineCommonAncestor(factoryMethod.getReturnType(), commonType); |
|
|
|
|
|
|
|
if (commonType == null) { |
|
|
|
|
|
|
|
// Ambiguous return types found: return null to indicate "not determinable".
|
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (commonType != null) { |
|
|
|
if (commonType != null) { |
|
|
|
// Clear return type found: all factory methods return same type.
|
|
|
|
// Clear return type found: all factory methods return same type.
|
|
|
|
if (cache) { |
|
|
|
mbd.factoryMethodReturnType = (uniqueCandidate != null ? |
|
|
|
mbd.resolvedFactoryMethodReturnType = commonType; |
|
|
|
ResolvableType.forMethodReturnType(uniqueCandidate) : ResolvableType.forClass(commonType)); |
|
|
|
} |
|
|
|
|
|
|
|
return commonType; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
// Ambiguous return types found: return null to indicate "not determinable".
|
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return commonType; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
|