Merge branch '6.1.x'

# Conflicts:
#	spring-beans/src/main/java/org/springframework/beans/factory/support/GenericTypeAwareAutowireCandidateResolver.java
This commit is contained in:
Juergen Hoeller
2024-04-08 22:41:02 +02:00
5 changed files with 346 additions and 254 deletions

View File

@@ -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

View File

@@ -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