Merge branch '6.1.x'
# Conflicts: # spring-beans/src/main/java/org/springframework/beans/factory/support/GenericTypeAwareAutowireCandidateResolver.java
This commit is contained in:
@@ -524,42 +524,73 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
// Check manually registered singletons.
|
||||
Object beanInstance = getSingleton(beanName, false);
|
||||
if (beanInstance != null && beanInstance.getClass() != NullBean.class) {
|
||||
|
||||
// Determine target for FactoryBean match if necessary.
|
||||
if (beanInstance instanceof FactoryBean<?> factoryBean) {
|
||||
if (!isFactoryDereference) {
|
||||
Class<?> type = getTypeForFactoryBean(factoryBean);
|
||||
return (type != null && typeToMatch.isAssignableFrom(type));
|
||||
}
|
||||
else {
|
||||
return typeToMatch.isInstance(beanInstance);
|
||||
}
|
||||
}
|
||||
else if (!isFactoryDereference) {
|
||||
if (typeToMatch.isInstance(beanInstance)) {
|
||||
// Direct match for exposed instance?
|
||||
return true;
|
||||
}
|
||||
else if (typeToMatch.hasGenerics() && containsBeanDefinition(beanName)) {
|
||||
// Generics potentially only match on the target class, not on the proxy...
|
||||
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
|
||||
Class<?> targetType = mbd.getTargetType();
|
||||
if (targetType != null && targetType != ClassUtils.getUserClass(beanInstance)) {
|
||||
// Check raw class match as well, making sure it's exposed on the proxy.
|
||||
Class<?> classToMatch = typeToMatch.resolve();
|
||||
if (classToMatch != null && !classToMatch.isInstance(beanInstance)) {
|
||||
if (type == null) {
|
||||
return false;
|
||||
}
|
||||
if (typeToMatch.isAssignableFrom(type)) {
|
||||
return true;
|
||||
}
|
||||
else if (typeToMatch.hasGenerics() && containsBeanDefinition(beanName)) {
|
||||
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
|
||||
ResolvableType targetType = mbd.targetType;
|
||||
if (targetType == null) {
|
||||
targetType = mbd.factoryMethodReturnType;
|
||||
}
|
||||
if (targetType == null) {
|
||||
return false;
|
||||
}
|
||||
if (typeToMatch.isAssignableFrom(targetType)) {
|
||||
return true;
|
||||
Class<?> targetClass = targetType.resolve();
|
||||
if (targetClass != null && FactoryBean.class.isAssignableFrom(targetClass)) {
|
||||
Class<?> classToMatch = typeToMatch.resolve();
|
||||
if (classToMatch != null && !FactoryBean.class.isAssignableFrom(classToMatch) &&
|
||||
!classToMatch.isAssignableFrom(targetType.toClass())) {
|
||||
return typeToMatch.isAssignableFrom(targetType.getGeneric());
|
||||
}
|
||||
}
|
||||
else {
|
||||
return typeToMatch.isAssignableFrom(targetType);
|
||||
}
|
||||
}
|
||||
ResolvableType resolvableType = mbd.targetType;
|
||||
if (resolvableType == null) {
|
||||
resolvableType = mbd.factoryMethodReturnType;
|
||||
}
|
||||
return (resolvableType != null && typeToMatch.isAssignableFrom(resolvableType));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
else if (isFactoryDereference) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Actual matching against bean instance...
|
||||
if (typeToMatch.isInstance(beanInstance)) {
|
||||
// Direct match for exposed instance?
|
||||
return true;
|
||||
}
|
||||
else if (typeToMatch.hasGenerics() && containsBeanDefinition(beanName)) {
|
||||
// Generics potentially only match on the target class, not on the proxy...
|
||||
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
|
||||
Class<?> targetType = mbd.getTargetType();
|
||||
if (targetType != null && targetType != ClassUtils.getUserClass(beanInstance)) {
|
||||
// Check raw class match as well, making sure it's exposed on the proxy.
|
||||
Class<?> classToMatch = typeToMatch.resolve();
|
||||
if (classToMatch != null && !classToMatch.isInstance(beanInstance)) {
|
||||
return false;
|
||||
}
|
||||
if (typeToMatch.isAssignableFrom(targetType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
ResolvableType resolvableType = mbd.targetType;
|
||||
if (resolvableType == null) {
|
||||
resolvableType = mbd.factoryMethodReturnType;
|
||||
}
|
||||
return (resolvableType != null && typeToMatch.isAssignableFrom(resolvableType));
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
|
||||
// null instance registered
|
||||
|
||||
@@ -103,23 +103,6 @@ public class GenericTypeAwareAutowireCandidateResolver extends SimpleAutowireCan
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Pre-existing target type: In case of a generic FactoryBean type,
|
||||
// unwrap nested generic type when matching a non-FactoryBean type.
|
||||
Class<?> resolvedClass = targetType.resolve();
|
||||
if (resolvedClass != null && FactoryBean.class.isAssignableFrom(resolvedClass)) {
|
||||
Class<?> typeToBeMatched = dependencyType.resolve();
|
||||
if (typeToBeMatched != null && !FactoryBean.class.isAssignableFrom(typeToBeMatched) &&
|
||||
!typeToBeMatched.isAssignableFrom(resolvedClass)) {
|
||||
targetType = targetType.getGeneric();
|
||||
if (descriptor.fallbackMatchAllowed()) {
|
||||
// Matching the Class-based type determination for FactoryBean
|
||||
// objects in the lazy-determination getType code path below.
|
||||
targetType = ResolvableType.forClass(targetType.resolve());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (targetType == null) {
|
||||
@@ -146,6 +129,23 @@ public class GenericTypeAwareAutowireCandidateResolver extends SimpleAutowireCan
|
||||
if (cacheType) {
|
||||
rbd.targetType = targetType;
|
||||
}
|
||||
|
||||
// Pre-declared target type: In case of a generic FactoryBean type,
|
||||
// unwrap nested generic type when matching a non-FactoryBean type.
|
||||
Class<?> targetClass = targetType.resolve();
|
||||
if (targetClass != null && FactoryBean.class.isAssignableFrom(targetClass)) {
|
||||
Class<?> classToMatch = dependencyType.resolve();
|
||||
if (classToMatch != null && !FactoryBean.class.isAssignableFrom(classToMatch) &&
|
||||
!classToMatch.isAssignableFrom(targetClass)) {
|
||||
targetType = targetType.getGeneric();
|
||||
if (descriptor.fallbackMatchAllowed()) {
|
||||
// Matching the Class-based type determination for FactoryBean
|
||||
// objects in the lazy-determination getType code path above.
|
||||
targetType = ResolvableType.forClass(targetType.resolve());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (descriptor.fallbackMatchAllowed()) {
|
||||
// Fallback matches allow unresolvable generics, e.g. plain HashMap to Map<String,String>;
|
||||
// and pragmatically also java.util.Properties to any Map (since despite formally being a
|
||||
|
||||
Reference in New Issue
Block a user