spring GenericTypeAwareAutowireCandidateResolver 源码
spring GenericTypeAwareAutowireCandidateResolver 代码
文件路径:/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericTypeAwareAutowireCandidateResolver.java
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.support;
import java.lang.reflect.Method;
import java.util.Properties;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
/**
* Basic {@link AutowireCandidateResolver} that performs a full generic type
* match with the candidate's type if the dependency is declared as a generic type
* (e.g. {@code Repository<Customer>}).
*
* <p>This is the base class for
* {@link org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver},
* providing an implementation all non-annotation-based resolution steps at this level.
*
* @author Juergen Hoeller
* @since 4.0
*/
public class GenericTypeAwareAutowireCandidateResolver extends SimpleAutowireCandidateResolver
implements BeanFactoryAware, Cloneable {
@Nullable
private BeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Nullable
protected final BeanFactory getBeanFactory() {
return this.beanFactory;
}
@Override
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
if (!super.isAutowireCandidate(bdHolder, descriptor)) {
// If explicitly false, do not proceed with any other checks...
return false;
}
return checkGenericTypeMatch(bdHolder, descriptor);
}
/**
* Match the given dependency type with its generic type information against the given
* candidate bean definition.
*/
protected boolean checkGenericTypeMatch(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
ResolvableType dependencyType = descriptor.getResolvableType();
if (dependencyType.getType() instanceof Class) {
// No generic type -> we know it's a Class type-match, so no need to check again.
return true;
}
ResolvableType targetType = null;
boolean cacheType = false;
RootBeanDefinition rbd = null;
if (bdHolder.getBeanDefinition() instanceof RootBeanDefinition) {
rbd = (RootBeanDefinition) bdHolder.getBeanDefinition();
}
if (rbd != null) {
targetType = rbd.targetType;
if (targetType == null) {
cacheType = true;
// First, check factory method return type, if applicable
targetType = getReturnTypeForFactoryMethod(rbd, descriptor);
if (targetType == null) {
RootBeanDefinition dbd = getResolvedDecoratedDefinition(rbd);
if (dbd != null) {
targetType = dbd.targetType;
if (targetType == null) {
targetType = getReturnTypeForFactoryMethod(dbd, descriptor);
}
}
}
}
}
if (targetType == null) {
// Regular case: straight bean instance, with BeanFactory available.
if (this.beanFactory != null) {
Class<?> beanType = this.beanFactory.getType(bdHolder.getBeanName());
if (beanType != null) {
targetType = ResolvableType.forClass(ClassUtils.getUserClass(beanType));
}
}
// Fallback: no BeanFactory set, or no type resolvable through it
// -> best-effort match against the target class if applicable.
if (targetType == null && rbd != null && rbd.hasBeanClass() && rbd.getFactoryMethodName() == null) {
Class<?> beanClass = rbd.getBeanClass();
if (!FactoryBean.class.isAssignableFrom(beanClass)) {
targetType = ResolvableType.forClass(ClassUtils.getUserClass(beanClass));
}
}
}
if (targetType == null) {
return true;
}
if (cacheType) {
rbd.targetType = targetType;
}
if (descriptor.fallbackMatchAllowed() &&
(targetType.hasUnresolvableGenerics() || targetType.resolve() == Properties.class)) {
// 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
// Map<Object,Object>, java.util.Properties is usually perceived as a Map<String,String>).
return true;
}
// Full check for complex generic type match...
return dependencyType.isAssignableFrom(targetType);
}
@Nullable
protected RootBeanDefinition getResolvedDecoratedDefinition(RootBeanDefinition rbd) {
BeanDefinitionHolder decDef = rbd.getDecoratedDefinition();
if (decDef != null && this.beanFactory instanceof ConfigurableListableBeanFactory clbf) {
if (clbf.containsBeanDefinition(decDef.getBeanName())) {
BeanDefinition dbd = clbf.getMergedBeanDefinition(decDef.getBeanName());
if (dbd instanceof RootBeanDefinition) {
return (RootBeanDefinition) dbd;
}
}
}
return null;
}
@Nullable
protected ResolvableType getReturnTypeForFactoryMethod(RootBeanDefinition rbd, DependencyDescriptor descriptor) {
// Should typically be set for any kind of factory method, since the BeanFactory
// pre-resolves them before reaching out to the AutowireCandidateResolver...
ResolvableType returnType = rbd.factoryMethodReturnType;
if (returnType == null) {
Method factoryMethod = rbd.getResolvedFactoryMethod();
if (factoryMethod != null) {
returnType = ResolvableType.forMethodReturnType(factoryMethod);
}
}
if (returnType != null) {
Class<?> resolvedClass = returnType.resolve();
if (resolvedClass != null && descriptor.getDependencyType().isAssignableFrom(resolvedClass)) {
// Only use factory method metadata if the return type is actually expressive enough
// for our dependency. Otherwise, the returned instance type may have matched instead
// in case of a singleton instance having been registered with the container already.
return returnType;
}
}
return null;
}
/**
* This implementation clones all instance fields through standard
* {@link Cloneable} support, allowing for subsequent reconfiguration
* of the cloned instance through a fresh {@link #setBeanFactory} call.
* @see #clone()
*/
@Override
public AutowireCandidateResolver cloneIfNecessary() {
try {
return (AutowireCandidateResolver) clone();
}
catch (CloneNotSupportedException ex) {
throw new IllegalStateException(ex);
}
}
}
相关信息
相关文章
spring AbstractAutowireCapableBeanFactory 源码
spring AbstractBeanDefinition 源码
spring AbstractBeanDefinitionReader 源码
spring AutowireCandidateQualifier 源码
spring AutowireCandidateResolver 源码
spring BeanDefinitionBuilder 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦