UML
AutowireCandidateResolver
**
* Strategy interface for determining whether a specific bean definition
* qualifies as an autowire candidate for a specific dependency.
* <p>用于确定特定beanDefinition是否有资格作为特定依赖项的自动装配候选的策略接口</p>
* @author Juergen Hoeller
* @author Mark Fisher
* @since 2.5
*/
public interface AutowireCandidateResolver {
/**
* <p>确定给定的beanDefinition是否可以自动注入。只对@Autowired注解有效,配置文件中可以通过property显示注入</p>
* Determine whether the given bean definition qualifies as an
* autowire candidate for the given dependency.
* <p>确定给定的beanDefinition是否符合给定依赖项的自动装配候选条件。</p>
* <p>The default implementation checks
* {@link org.springframework.beans.factory.config.BeanDefinition#isAutowireCandidate()}.
* <p>默认实现{@link org.springframework.beans.factory.config.BeanDefinition#isAutowireCandidate()}</p>
* @param bdHolder the bean definition including bean name and aliases
* -- beanDefinition,包括bean名和别名封装对象
* @param descriptor the descriptor for the target method parameter or field
* -- 目标方法参数或字段的描述符
* @return whether the bean definition qualifies as autowire candidate
* -- 给定的beanDefinition是否可以自动注入
* @see org.springframework.beans.factory.config.BeanDefinition#isAutowireCandidate()
*/
default boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
return bdHolder.getBeanDefinition().isAutowireCandidate();
}
/**
* <p>确定descriptor确实需要注入</p>
* Determine whether the given descriptor is effectively required.
* <p>确定是否确实需要给定的描述符。</p>
* <p>The default implementation checks {@link DependencyDescriptor#isRequired()}.
* <p>默认实现检查 {@link DependencyDescriptor#isRequired()}</p>
* @param descriptor the descriptor for the target method parameter or field
* -- 目标方法参数或字段描述符
* @return whether the descriptor is marked as required or possibly indicating
* non-required status some other way (e.g. through a parameter annotation)
* -- 描述符是否标记为必需,或者是否可能通过其他方式(例如通过参数注释)指示非必需状态
* @since 5.0
* @see DependencyDescriptor#isRequired()
*/
default boolean isRequired(DependencyDescriptor descriptor) {
return descriptor.isRequired();
}
/**
* <p>表示desciptor有没有@Qualifier注解或qualifier标准修饰</p>
* Determine whether the given descriptor declares a qualifier beyond the type
* (typically - but not necessarily - a specific kind of annotation).
* <p>确定给定的描述符是否声明了类型之外的限定符(通常-但不一定-特定类型的注释)</p>
* <p>The default implementation returns {@code false}.
* <p>默认实现返回false</p>
* @param descriptor the descriptor for the target method parameter or field
* -- 目标方法参数或字段的描述符
* @return whether the descriptor declares a qualifier, narrowing the candidate
* status beyond the type match
* -- 描述符是否声明限定词,将候选状态缩小到类型匹配之外
* @since 5.1
* @see org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver#hasQualifier
*/
default boolean hasQualifier(DependencyDescriptor descriptor) {
return false;
}
/**
* Determine whether a default value is suggested for the given dependency.
* <p>确定是否建议给定依赖项的默认值</p>
* <p>The default implementation simply returns {@code null}.
* <p>默认实现只是返回null</p>
* @param descriptor the descriptor for the target method parameter or field
* -- 目标方法参数或字段的描述符
* @return the value suggested (typically an expression String),
* or {@code null} if none found
* -- 建议的值(通常是表达式字符串),如果找不到,则为null
* @since 3.0
*/
@Nullable
default Object getSuggestedValue(DependencyDescriptor descriptor) {
return null;
}
/**
* Build a proxy for lazy resolution of the actual dependency target,
* if demanded by the injection point.
* <p>BeanDefinition描述了一个bean实例,该实例具有属性值,构造函数参数值以及
* 具体实现所提供的更多信息</p>
* <p>The default implementation simply returns {@code null}.
* <p>默认实现指示返回{@code null}</p>
* @param descriptor the descriptor for the target method parameter or field
* -- 目标方法参数或字段描述符
* @param beanName the name of the bean that contains the injection point
* -- 包含注入点的bean名
* @return the lazy resolution proxy for the actual dependency target,
* or {@code null} if straight resolution is to be performed
* -- 实际依赖关系目标的惰性解决方案代理;如果要执行直接解决方案,则为null
* @since 4.0
*/
@Nullable
default Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) {
return null;
}
}
SimpleAutowireCandidateResolver
/**
* {@link AutowireCandidateResolver} implementation to use when no annotation
* support is available. This implementation checks the bean definition only.
* <p>没有注释支持可用时使用的AutowireCandidateResolver实现。此实现仅检查bean定义</p>
* @author Mark Fisher
* @author Juergen Hoeller
* @since 2.5
*/
public class SimpleAutowireCandidateResolver implements AutowireCandidateResolver {
/**
* 确定给定的beanDefinition是否可以自动注入。只对@Autowired注解有效,配置文件中可以通过property显示注入
* <p>简单返回bdHolder的BeanDefinition对象的是否可以自动注入标记结果【{@link AbstractBeanDefinition#isAutowireCandidate()}】</p>
* @param bdHolder the bean definition including bean name and aliases
* -- beanDefinition,包括bean名和别名封装对象
* @param descriptor the descriptor for the target method parameter or field
* -- 目标方法参数或字段的描述符
* @return 给定的beanDefinition是否可以自动注入
*/
@Override
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
return bdHolder.getBeanDefinition().isAutowireCandidate();
}
/**
* 确定descriptor是否需要依赖项(descriptor是否设置了需要依赖项)。
* @param descriptor the descriptor for the target method parameter or field
* -- 目标方法参数或字段描述符
*/
@Override
public boolean isRequired(DependencyDescriptor descriptor) {
return descriptor.isRequired();
}
@Override
@Nullable
public Object getSuggestedValue(DependencyDescriptor descriptor) {
return null;
}
@Override
@Nullable
public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) {
return null;
}
}
GenericTypeAwareAutowireCandidateResolver
/**
* 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. Repository<Customer>).
* <p>基于{@link AutowireCandidateResolver},如果将依赖项声明为泛型类型(例如Respository<Customer>),
* 则执行与候选者类型的完全通用类型匹配</p>
*
* <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.
* <p>这是{@link org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver},
* 的基类,提供此级别上所有基于非注释的解析步骤的实现</p>
* @author Juergen Hoeller
* @since 4.0
*/
public class GenericTypeAwareAutowireCandidateResolver extends SimpleAutowireCandidateResolver
implements BeanFactoryAware {
@Nullable
private BeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Nullable
protected final BeanFactory getBeanFactory() {
return this.beanFactory;
}
/**
* 确定给定的beanDefinition是否可以自动注入。只对@Autowired注解有效,配置文件中可以通过property显示注入:
* <ol>
* <li>如果bdHolder的BeanDefinition对象的不可以自动注入标记结果,直接返回false,表示不可以自动注入</li>
* <li>检查泛型类型匹配【{@link #checkGenericTypeMatch(BeanDefinitionHolder, DependencyDescriptor)}】
* ,并返回匹配结果</li>
* </ol>
* @param bdHolder beanDefinition,包括bean名和别名封装对象
* @param descriptor 目标方法参数或字段的描述符
* @return 给定的beanDefinition是否可以自动注入
*/
@Override
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
//super.isAutowireCandidate实现简单返回bdHolder的BeanDefinition对象的是否可以自动注入标记结果
// 【AbstractBeanDefinition.isAutowireCandidate()】
//优先交由父级判断,如果父级判断结果表明不可以,则不再继续本类处理
if (!super.isAutowireCandidate(bdHolder, descriptor)) {
// If explicitly false, do not proceed with any other checks...
// 如果明确为假,则不要进行任何其他检查
return false;
}
//检查泛型类型匹配
return checkGenericTypeMatch(bdHolder, descriptor);
}
/**
* <p>检查泛型类型匹配:
* <ol>
* <li>让descriptor为包装的参数/字段构建一个ResolvableType对象【变量 dependencType】</li>
* <li>如果dependencyType的JavaType是Class对象实例,就直接返回true,表示可以自动注入,
* 因为这个是Class类型的匹配项,没有泛型</li>
* <li>【<b>获取目标类型targetType</b>】
* <ol>
* <li>定义用于引用目标类型的ResolvableType对象,默认为null【变量 targetType】</li>
* <li>定义表示需要缓存类型标记,默认为false 【变量 cacheType】</li>
* <li>定义用于引用bhHolder的RootBeanDefinition对象的RootBeanDefinition对象,默认为null
* 【变量 rbd】</li>
* <li>如果bdHolder的BeanDefinition对象是RootBeanDefinition对象实例,让rbd引用
* bhHolder的RootBeanDefinition对象</li>
* <li>如果rbd不为null:
* <ol>
* <li>【<b>尝试获取rbd的缓存属性来得到targetType</b>】让targetType引用rbd的目标类型【{@link RootBeanDefinition#targetType}】</li>
* <li>【<b>尝试通过rbd的配置获取targetType,如获取工厂方法的返回类型</b>】如果targetType为null:
* <ol>
* <li>设置cacheType为true,表示需要缓存类型</li>
* <li>获取rbd工厂方法的返回类型,只有解析出来的返回类型与descriptor包装的依赖类型匹配(不考虑泛型匹配)
* 才返回工厂方法的返回类型,将结果赋值给targetType</li>
* <li>如果targetType为null:
* <ol>
* <li>获取rbd所指bean名在beanFactory中的合并后RootBeanDefinition【变量 dbd】</li>
* <li>如果dbd不为null:
* <ol>
* <li>让targetType引用dbd的目标类型</li>
* <li>如果targetType为null,获取dbd工厂方法的返回类型,只有解析出来的返回类型与descriptor包装的
* 依赖类型匹配(不考虑泛型匹配)才返回工厂方法的返回类型</li>
* </ol>
* </li>
* </ol>
* </li>
* </ol>
* </li>
* </ol>
* </li>
* <li>如果targetType为null:
* <ol>
* <li>【<b>尝试使用BeanFactory获取targetType</b>】如果beanFactory不为null:
* <ol>
* <li>从beanFactory中获取bhHolder所包装的bean名的bean类型【变量 beanType】</li>
* <li>如果beanType不为null,将beanType封装成ResovleableType对象赋值给targetType</li>
* </ol>
* </li>
* <li>【<b>尝试获取rbd的beanClass属性作为targetType</b>】targetType为null 且 rbd不为null 且 rbd有
* 指定了bean类 但 rbd没有工厂方法名
* <ol>
* <li>获取rbd的bean类【{@link RootBeanDefinition#getBeanClass()},变量 beanClass】</li>
* <li>如果bean类不是FactoryBean的实例,将beanType封装成ResovleableType对象赋值给targetType</li>
* </ol>
* </li>
* </ol>
* </li>
* </ol>
* </li>
* <li>【<b>默认情况下,Spring对无法检查的情况默认是给它放行的,可能是出于最大可用性的考虑吧</b>】:
* <ol>
* <li>如果targetType还是为null,默认返回true,让其可以自动注入</li>
* <li>如果需要缓存目标类型,让rbd的目标类型【{@link RootBeanDefinition#targetType}】引用targetType</li>
* <li>如果descriptor允许回退匹配 且 (targetType具有无法解析的泛型 || targetType的Class对象是Properties类对象),
* 返回true,让其可以自动注入</li>
* </ol>
* </li>
* <li>【<b>处理能拿到targetType且targetType可进行检查的情况</b>】判断targetType是否属于dependencyType类型【加上了泛型检查】,并将结果返回出去</li>
* </ol>
* </p>
* Match the given dependency type with its generic type information against the given
* candidate bean definition.
* <p>将给定的依赖关系类型及其泛型信息与给定的候选beanDefinition进行匹配</p>
* @param bdHolder beanDefinition,包括bean名和别名封装对象
* @param descriptor 目标方法参数或字段的描述符
* @return 给定的beanDefinition是否可以自动注入
*/
protected boolean checkGenericTypeMatch(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
//让descriptor为包装的参数/字段构建一个ResolvableType对象
ResolvableType dependencyType = descriptor.getResolvableType();
//如果dependencyType的JavaType是Class对象实例
if (dependencyType.getType() instanceof Class) {
// No generic type -> we know it's a Class type-match, so no need to check again.
// 没有泛型类型 -> 我们知道这是一个Class类型匹配项,因此无需再次检查
//返回true,表示可以自动注入,因为这个是Class类型的匹配项,没有泛型
return true;
}
//定义用于引用目标类型的ResolvableType对象,默认为null
ResolvableType targetType = null;
//定义表示需要缓存类型标记,默认为false
boolean cacheType = false;
//定义用于引用bhHolder的RootBeanDefinition对象的RootBeanDefinition对象,默认为null
RootBeanDefinition rbd = null;
//如果bdHolder的BeanDefinition对象是RootBeanDefinition对象实例
if (bdHolder.getBeanDefinition() instanceof RootBeanDefinition) {
//让rbd引用bhHolder的RootBeanDefinition对象
rbd = (RootBeanDefinition) bdHolder.getBeanDefinition();
}
//如果rbd不为null
if (rbd != null) {
//让targetType引用rbd的目标类型
targetType = rbd.targetType;
//如果targetType为null
if (targetType == null) {
//设置cacheType为true,表示需要缓存类型
cacheType = true;
// First, check factory method return type, if applicable
// 首先检查工厂方法的返回类型(如果适用)
// 获取rbd工厂方法的返回类型,只有解析出来的返回类型与descriptor包装的依赖类型匹配(不考虑泛型匹配)
// 才返回工厂方法的返回类型:
targetType = getReturnTypeForFactoryMethod(rbd, descriptor);
//这里应该是Spring想尽可能的拿到targetType所做的一下保障机制
//如果targetType为null
if (targetType == null) {
//获取rbd所指bean名在beanFactory中的合并后RootBeanDefinition:
RootBeanDefinition dbd = getResolvedDecoratedDefinition(rbd);
//如果dbd不为null
if (dbd != null) {
//让targetType引用dbd的目标类型
targetType = dbd.targetType;
if (targetType == null) {
//获取dbd工厂方法的返回类型,只有解析出来的返回类型与descriptor包装的依赖类型匹配(不考虑泛型匹配)
// 才返回工厂方法的返回类型
targetType = getReturnTypeForFactoryMethod(dbd, descriptor);
}
}
}
}
}
//如果targetType为null
if (targetType == null) {
// Regular case: straight bean instance, with BeanFactory available.
// 常规情况:纯bean实例,可以使用BeanFactory
//如果beanFactory不为null
if (this.beanFactory != null) {
//从beanFactory中获取bhHolder所包装的bean名的bean类型
Class<?> beanType = this.beanFactory.getType(bdHolder.getBeanName());
//如果beanType不为null
if (beanType != null) {
//ClassUtils.getUserClass:如果beanType是CGLIB生成的子类,则返回该子类的父类,否则直接返回要检查的类
//将beanType封装成ResovleableType对象赋值给targetType
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.
// 回退:没有BeanFactory设置,或者没有可通过它解析得类型->与目标类的最大努力匹配(如果适用)
// targetType为null 且 rbd不为null 且 rbd有指定了bean类 但 rbd没有工厂方法名
if (targetType == null && rbd != null && rbd.hasBeanClass() && rbd.getFactoryMethodName() == null) {
//获取rbd的bean类
Class<?> beanClass = rbd.getBeanClass();
//如果bean类不是FactoryBean的实例
if (!FactoryBean.class.isAssignableFrom(beanClass)) {
///ClassUtils.getUserClass:如果beanType是CGLIB生成的子类,则返回该子类的父类,否则直接返回要检查的类
//将beanType封装成ResovleableType对象赋值给targetType
targetType = ResolvableType.forClass(ClassUtils.getUserClass(beanClass));
}
}
}
//在找不到目标类型的情况下,默认返回true,让其可以自动注入;TODO 没理解为什么
if (targetType == null) {
return true;
}
//如果需要缓存目标类型
if (cacheType) {
//让rbd的目标类型引用targetType
rbd.targetType = targetType;
}
//如果descriptor允许回退匹配 且 (targetType具有无法解析的泛型 || targetType的Class对象是Properties类对象)
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>).
//后备匹配允许使用无法解析的泛型,例如从HashMap到Map<String,String>;
// 并且从实用上讲,任何Map都有java.util.Properties(因为尽管正式是Map<Object,Object>,
// 所以java.util.Properties通常被视为Map<String,String>).
return true;
}
// Full check for complex generic type match...
// 全面检查复杂的泛型类型匹配
// 这里的判断,是针对常规匹配和回退匹配的检查
// 判断targetType是否属于dependencyType类型【加上了泛型检查】,并将结果返回出去
return dependencyType.isAssignableFrom(targetType);
}
/**
* 获取rbd所指bean名在beanFactory中的合并后RootBeanDefinition:
* <ol>
* <li>获取rdb的beanDefinition,包括bean名和别名封装对象【变量 decDef】</li>
* <li>如果decDef不为null 且 该工厂是ConfiguableLisableBeanFactory实例:
* <ol>
* <li>将beanFactory强转成ConfigurableLisatableBeanFactory对象【变量 clbf】</li>
* <li>如果clbf包含具有decDef所指bean名的beanDefinition:
* <ol>
* <li>获取defDef所指bean名的合并后BeanDefinition【变量dbd】</li>
* <li>如果dbd是RootBeanDefinition对象,将dbd强转为RootBeanDefinition对象返回出去</li>
* </ol>
* </li>
* </ol>
* </li>
* <li>默认返回null</li>
* </ol>
* @param rbd bdHolder的RootBeanDefinition对象
* @return rbd所指bean名在beanFactory中的合并后RootBeanDefinition;如果没有,就返回null
*/
@Nullable
protected RootBeanDefinition getResolvedDecoratedDefinition(RootBeanDefinition rbd) {
//获取rdb的beanDefinition,包括bean名和别名封装对象
BeanDefinitionHolder decDef = rbd.getDecoratedDefinition();
//如果decDef不为null 且 该工厂是ConfiguableLisableBeanFactory实例
if (decDef != null && this.beanFactory instanceof ConfigurableListableBeanFactory) {
//将beanFactory强转成ConfigurableLisatableBeanFactory对象
ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory) this.beanFactory;
//如果clbf包含具有decDef所指bean名的beanDefinition
if (clbf.containsBeanDefinition(decDef.getBeanName())) {
//获取defDef所指bean名的合并后BeanDefinition
BeanDefinition dbd = clbf.getMergedBeanDefinition(decDef.getBeanName());
//如果dbd是RootBeanDefinition对象
if (dbd instanceof RootBeanDefinition) {
//将dbd强转为RootBeanDefinition对象返回出去
return (RootBeanDefinition) dbd;
}
}
}
//1.deDef为null
//2.该工厂不是ConfigableLisbaleBeanFactory实例
//3.该工厂没有包含具有decDef的bean名的beanDefinition对象,
//4.得到的beanDefinition对象不是RootBeanDefinition对象
//默认返回null
return null;
}
/**
* 获取工厂方法的返回类型,只有解析出来的返回类型与descriptor包装的依赖类型匹配(不考虑泛型匹配)才返回工厂方法的返回类型:
* <ol>
* <li>获取rbd缓存下来的通用类型的工厂方法的返回类型【变量 returnType】</li>
* <li>如果returnType为null:
* <ol>
* <li>获取rbd的解析的工厂方法对象【变量 factoryMethod】</li>
* <li>如果factoryMethod不为null,获取factoryMethod的返回类型的ResolvableType对象并赋值给returnType</li>
* </ol>
* </li>
* <li>如果returnType不为null:
* <ol>
* <li>将returnType解析成Class对象【变量 resolvedClass】</li>
* <li>如果resolvedClass不为null 且 resolvedClass是属于descriptor包装的依赖类型【只是检查Class,并没有对泛型做检查】
* ,就返回returnType</li>
* </ol>
* </li>
* <li>没有解析到返回类型时 或者 解析returnType出来的Class对象不属于descriptor包装的依赖类型时,返回null</li>
* </ol>
* @param rbd bdHolder的RootBeanDefinition对象
* @param descriptor 目标方法参数或字段的描述符
* @return 只有解析出来的返回类型与descriptor包装的依赖类型匹配才返回工厂方法的返回类型
*/
@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...
// 通用应为任何一种工厂方法设置,因为BeanFactory在联系AutowireCandidateResolver之前会预先
// 解析它们
//获取rbd缓存下来的通用类型的工厂方法的返回类型
ResolvableType returnType = rbd.factoryMethodReturnType;
// 如果返回类型为null
if (returnType == null) {
//获取rbd的解析的工厂方法对象
Method factoryMethod = rbd.getResolvedFactoryMethod();
//如果factoryMethod不为null
if (factoryMethod != null) {
//获取factoryMethod的返回类型的ResolvableType对象
returnType = ResolvableType.forMethodReturnType(factoryMethod);
}
}
//如果返回类型不为null
if (returnType != null) {
//将returnType解析成Class对象
Class<?> resolvedClass = returnType.resolve();
//如果resolvedClass不为null 且 resolvedClass是属于descriptor的包装的参数/字段的声明的(非泛型)类型【只是检查Class,
// 并没有对泛型做检查】
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;
}
}
//没有解析到返回类型时 或者 解析returnType出来的Class对象不属于descriptor包装的依赖类型,返回null
return null;
}
}
QualifierAnnotationAutowireCandidateResolver
/**
* {@link AutowireCandidateResolver} implementation that matches bean definition qualifiers
* against {@link Qualifier qualifier annotations} on the field or parameter to be autowired.
* Also supports suggested expression values through a {@link Value value} annotation.
* <p>AutowireCandidateResolver实现,将bean定义限定符与要自动连接的字段或参数上的限定符相匹配。还
* 通过值注释支持建议的表达式值</p>
*
* <p>Also supports JSR-330's {@link javax.inject.Qualifier} annotation, if available.
* <p>如果可用,还支持JSR-330的{@link javax.inject.Qualifier}注解</p>
*
* @author Mark Fisher
* @author Juergen Hoeller
* @author Stephane Nicoll
* @since 2.5
* @see AutowireCandidateQualifier
* @see Qualifier
* @see Value
*/
public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwareAutowireCandidateResolver {
/**
* Spring支持的Qualifier注解缓存
*/
private final Set<Class<? extends Annotation>> qualifierTypes = new LinkedHashSet<>(2);
/**
* Value注解类型,默认使用{@link Value}
*/
private Class<? extends Annotation> valueAnnotationType = Value.class;
/**
* Create a new QualifierAnnotationAutowireCandidateResolver
* for Spring's standard {@link Qualifier} annotation.
* <p>为Spring的标准Qualifier注解创建一个新的QualifierAnnotationAutowireCandidateResovler.</p>
* <p>Also supports JSR-330's {@link javax.inject.Qualifier} annotation, if available.
* <p>如果可用,还支持JSR-330的javax.inject.Qualifier批注</p>
*/
@SuppressWarnings("unchecked")
public QualifierAnnotationAutowireCandidateResolver() {
//添加Qualifier注解到qualifierTypes中
this.qualifierTypes.add(Qualifier.class);
try {
//如果引入了JSR-330库,会将javax.inject.Qualifier也提交到qualifierType中
this.qualifierTypes.add((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Qualifier",
QualifierAnnotationAutowireCandidateResolver.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
// JSR-330 API 不可用-只需跳过
}
}
/**
* Create a new QualifierAnnotationAutowireCandidateResolver
* for the given qualifier annotation type.
* <p>为给定的限定符注解类型一个新的QualifierAnnotationAutowireCandidateResolver</p>
* @param qualifierType the qualifier annotation to look for -- 要查找的限定符注解
*/
public QualifierAnnotationAutowireCandidateResolver(Class<? extends Annotation> qualifierType) {
//如果qualifierType为null,抛出异常
Assert.notNull(qualifierType, "'qualifierType' must not be null");
//添加qualifierType注解到qualifierTypes中
this.qualifierTypes.add(qualifierType);
//注意:这里只是添加qualifierType,但javax.inject.Qualifier,
// org.springframework.beans.factory.annotation.Qualifier是没有添加到qualifierTypes中的,
// 也就是说,通过该构造函数创建出来的对象只支持qualifierType。
}
/**
* Create a new QualifierAnnotationAutowireCandidateResolver
* for the given qualifier annotation types.
* <p>为给定的限定符注解类型创建一个新的QualifierAnnotationAutowireCandidateResolver</p>
* @param qualifierTypes the qualifier annotations to look for -- 要查找的限定符的注解
*/
public QualifierAnnotationAutowireCandidateResolver(Set<Class<? extends Annotation>> qualifierTypes) {
//如果qualifierType为null,抛出异常
Assert.notNull(qualifierTypes, "'qualifierTypes' must not be null");
//添加qualifierTypes注解到qualifierTypes中
this.qualifierTypes.addAll(qualifierTypes);
//注意:这里只是添加qualifierTypes,但javax.inject.Qualifier,
// org.springframework.beans.factory.annotation.Qualifier是没有添加到qualifierTypes中的,
// 也就是说,通过该构造函数创建出来的对象只支持qualifierTypes。
}
/**
* Register the given type to be used as a qualifier when autowiring.
* <p>注册给定类型以在自动装配时用作限定符</p>
* <p>This identifies qualifier annotations for direct use (on fields,
* method parameters and constructor parameters) as well as meta
* annotations that in turn identify actual qualifier annotations.
* <p>这标识了直接使用的限定符注解(在字段,方法参数和构造函数参数上)以及元标记,
* 后者又标识了实际的限定符注解</p>
* <p>This implementation only supports annotations as qualifier types.
* The default is Spring's {@link Qualifier} annotation which serves
* as a qualifier for direct use and also as a meta annotation.
* <p>此实现仅支持将注解作为限定符类型。默认的是Spring的Qualifier注解,它可以直接
* 用作为限定符,也可以作为meta注解</p>
* @param qualifierType the annotation type to register -- 要注册的注解类型
*/
public void addQualifierType(Class<? extends Annotation> qualifierType) {
//添加qualifierType注解到qualifierTypes中
this.qualifierTypes.add(qualifierType);
}
/**
* Set the 'value' annotation type, to be used on fields, method parameters
* and constructor parameters.
* <p>设置"value"注解类型,以用于字段,方法参数和构造函数参数</p>
* <p>The default value annotation type is the Spring-provided
* {@link Value} annotation.
* <p>默认值注解类型是Spring提供的Value注解</p>
* <p>This setter property exists so that developers can provide their own
* (non-Spring-specific) annotation type to indicate a default value
* expression for a specific argument.
* <p>存在此setter属性,以便开发人员可以提供自己的(非特定于Spring的)注解类型,
* 以指示特定参数的默认值表达式</p>
*/
public void setValueAnnotationType(Class<? extends Annotation> valueAnnotationType) {
this.valueAnnotationType = valueAnnotationType;
}
/**
* <p>确定bbHolder是否可以自动装配(beanDefinition是否允许依赖注入,泛型类型是否匹配,限定符注解是否匹配):
* <ol>
* <li>引用父级匹配结果(beanDefinition是否允许依赖注入,泛型类型是否匹配)【变量 match】</li>
* <li>限定符注解匹配:
* <ol>
* <li>如果匹配【match】:
* <ol>
* <li>让match引用descriptor所包装的field/methodParamter对象的注解与bdHolder的beanDefinition匹配结果</li>
* <li>如果匹配【match】,尝试再检查方法上的注解:
* <ol>
* <li>获取desciptor包装的方法参数对象【变量 methodParamter】</li>
* <li>如果是method是构造函数或者method是无返回值方法:让match引用descriptor所包装的methodParam所属
* 的method的注解与bdHolder的beanDefinition匹配结果</li>
* </ol>
* </li>
* </ol>
* </li>
* </ol>
* </li>
* <li>返回匹配结果【match】</li>
* </ol>
* </p>
* Determine whether the provided bean definition is an autowire candidate.
* <p>确定所提供的beanDefinition是否为自动装配候选</p>
* <p>To be considered a candidate the bean's <em>autowire-candidate</em>
* attribute must not have been set to 'false'. Also, if an annotation on
* the field or parameter to be autowired is recognized by this bean factory
* as a <em>qualifier</em>, the bean must 'match' against the annotation as
* well as any attributes it may contain. The bean definition must contain
* the same qualifier or match by meta attributes. A "value" attribute will
* fallback to match against the bean name or an alias if a qualifier or
* attribute does not match.
* <p>要被视为候选对象,bean的autowire-candidate属性必须未设置为'false'.另外,
* 如果此beanFactory将要自动连接的字段或参数上的注解识别为限定符,则bean必须与该注解
* 及其可能包含的任何属性'匹配'.beanDefinition必须包含相同的限定符或按meta属性进行
* 匹配。如果限定符或属性不匹配,则'value'属性将回退与Bean名称或别名匹配</p>
* @param bdHolder – beanDefinition,包括bean名和别名封装对象
* @param descriptor – 目标方法参数或字段的描述符
* @see Qualifier
*/
@Override
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
//确定bdHolder的beanDefinition是否可以自动注入(beanDefinition是否允许依赖注入,泛型类型是否匹配,限定符注解/限定符信息是否匹配)
boolean match = super.isAutowireCandidate(bdHolder, descriptor);
//如果匹配
if (match) {
//让match引用descriptor所包装的field对象/methodParameter的注解与bdHolder的beanDefinition匹配结果
match = checkQualifiers(bdHolder, descriptor.getAnnotations());
//如果匹配,尝试再检查方法上的注解,因为限定符注解可能没有设置在field/methodParamaters上,而是加在方法上,所以检查一下方法
if (match) {
//获取desciptor包装的方法参数对象
MethodParameter methodParam = descriptor.getMethodParameter();
//如果有方法参数
if (methodParam != null) {
//获取方法参数所属的方法对象
Method method = methodParam.getMethod();
//method == null表示构造函数 void.class表示方法返回void
//如果是method是构造函数或者method是无返回值方法
if (method == null || void.class == method.getReturnType()) {
//methodParam.getMethodAnnotations():返回methodParam所属的method的注解,即加在方法上的注解
//让match引用descriptor所包装的methodParam所属的method的注解与bdHolder的beanDefinition匹配结果
match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations());
}
}
}
}
//返回匹配结果
return match;
}
/**
* <p>将descriptor的注解与bdHolder的beanDefinition匹配:
* <ol>
* <li>如果annotationsToSearche没有注解,返回true,表示匹配</li>
* <li>创建一个类型转换器实例,用于对注解/BeanDefinition的属性值的转换【变量 typeConverter】</li>
* <li>遍历annotationsToSearch,元素annotation:
* <ol>
* <li>【<b>先直接用annotation进行匹配</b>】:
* <ol>
* <li>获取annotation的的Class对象【变量 type】</li>
* <li>定义检查元注解标记,默认为true【变量 checkMeta】</li>
* <li>定义需要回退匹配元注解标记,默认为false</li>
* <li>如果anntationType是限定符注解:
* <ol>
* <li>如果annotation与bdHolder的beanDefinition不匹配时(匹配限定符),需要回退匹配元
* 注解标记【fallbackToMeta】设置为true,表示需要回退匹配元注解标记</li>
* <li>否则检查元注解【checkMeta】设置为false,表示不需要检查元注解</li>
* </ol>
* </li>
* </ol>
* </li>
* <li>【<b>用annotation里注解进行匹配</b>】:
* <ol>
* <li>如果需要检查元信息【checkMeta】:
* <ol>
* <li>定义一个找到限定符注解标记【变量 foundMeta 】,默认为false,表示未找到限定符注解</li>
* <li>遍历注解里的所有注解,元素为metaAnn:
* <ol>
* <li>获取metaAnn的Class对象【变量 metaType】</li>
* <li>如果anntationType是限定符注解:
* <ol>
* <li>设置找到元信息标记设置为true,表示找到了限定符注解</li>
* <li>如果(需要回退且metaAnn的value属性是空字符) 或者 metaAnn与bdHolder的
* beanDefinition不匹配(匹配限定符),返回false,表示不匹配</li>
* </ol>
* </li>
* </ol>
* </li>
* <li>如果需要回退检查元注解但没有找到限定符注解,返回false,表示不匹配</li>
* </ol>
* </li>
* </ol>
* </li>
* </ol>
* </li>
* <li>默认返回true,表示匹配</li>
* </ol>
* </p>
* Match the given qualifier annotations against the candidate bean definition.
* <p>将给定的限定符注解与候选beanDefinition匹配</p>
* @param bdHolder – beanDefinition,包括bean名和别名封装对象
* @param annotationsToSearch – descriptor所包装的属性/方法参数的注解
*/
protected boolean checkQualifiers(BeanDefinitionHolder bdHolder, Annotation[] annotationsToSearch) {
//如果annotationsToSearche没有注解
if (ObjectUtils.isEmpty(annotationsToSearch)) {
//返回true,默认让其通过
return true;
}
//创建一个类型转换器实例,用于对注解/BeanDefinition的属性值的转换
SimpleTypeConverter typeConverter = new SimpleTypeConverter();
//遍历annotationsToSearch
for (Annotation annotation : annotationsToSearch) {
//先直接用annotation进行匹配
//获取annotation的的Class对象
Class<? extends Annotation> type = annotation.annotationType();
//定义检查元注解标记,默认为true
boolean checkMeta = true;
//定义需要回退匹配元注解标记,默认为false
boolean fallbackToMeta = false;
//如果anntationType是限定符注解
if (isQualifier(type)) {
//如果annotation与bdHolder的beanDefinition不匹配时(匹配限定符)
if (!checkQualifier(bdHolder, annotation, typeConverter)) {
//需要回退匹配元注解标记设置为true,表示需要回退匹配元注解标记
fallbackToMeta = true;
}
else {
//检查元注解设置为false,表示不需要检查元注解
checkMeta = false;
}
}
//因为annotation有可能注解里配置限定符注解,所以可以检查一下注解里注解,需要注意的是该下面只检查一级嵌套,
//超过一级嵌套的层级都会忽略
//如果需要检查元信息
if (checkMeta) {
//找到限定符注解标记,默认为false,表示未找到限定符注解
boolean foundMeta = false;
//遍历注解里的所有注解
for (Annotation metaAnn : type.getAnnotations()) {
//获取metaAnn的Class对象
Class<? extends Annotation> metaType = metaAnn.annotationType();
//如果anntationType是限定符注解
if (isQualifier(metaType)) {
//找到元信息标记设置为true,表示找到了限定符注解
foundMeta = true;
// Only accept fallback match if @Qualifier annotation has a value...
// Otherwise it is just a marker for a custom qualifier annotation.
//仅当@Qualifier注解具有值时才接收回退匹配...
//否则是自定义限定符注解标记。
//如果(需要回退且metaAnn的value属性是空字符) 或者 metaAnn与bdHolder的beanDefinition不匹配(匹配限定符)
if ((fallbackToMeta && StringUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) ||
!checkQualifier(bdHolder, metaAnn, typeConverter)) {
//返回false,表示不匹配
return false;
}
}
}
//如果需要回退检查元注解但没有找到限定符注解
if (fallbackToMeta && !foundMeta) {
//返回false,表示不匹配
return false;
}
}
}
//默认返回true,表示匹配
return true;
}
/**
* <p>anntationType是否是限定符注解:
* <ol>
* <li>遍历qualifierTypes,元素为qualifierType:
* <ol>
* <li>如果annotationType与qualifierType相同 且 annotationType里有配置qualifierType注解,就返回true,
* 表示是可识别的限定符类型</li>
* </ol>
* </li>
* <li>默认返回false,表示不是可识别的限定符类型</li>
* </ol>
* </p>
* Checks whether the given annotation type is a recognized qualifier type.
* <p>检查给定的注解类型是否可识别的限定符类型</p>
*/
protected boolean isQualifier(Class<? extends Annotation> annotationType) {
//遍历qualifierTypes
for (Class<? extends Annotation> qualifierType : this.qualifierTypes) {
//如果annotationType与qualifierType相同 且 annotationType里有配置qualifierType注解
if (annotationType.equals(qualifierType) || annotationType.isAnnotationPresent(qualifierType)) {
//返回true,表示是可识别的限定符类型
return true;
}
}
//默认返回false,表示不是可识别的限定符类型
return false;
}
/**
* <p>将annotation与bdHolder的beanDefinition匹配(匹配限定符):
* <ol>
* <li>获取annotation的注解类型【变量 type】</li>
* <li>获取bdHolder的RootBeanDefinition对象【变量 bd】</li>
* <li>获取type在bd中限定符,即标签qualifier【变量 qualifier】</li>
* <li>如果qualifier为null,尝试用type的短类名获取</li>
* <li>【如果没有qualifier为null,表示<b>没有配置标签qualifier,则优先通过@Quanlifier进行匹配</b>】:
* <ol>
* <li>如果qualifier为null:
* <ol>
* <li>从bd的bean注解信息中获取type的注释对象【变量 targetAnnotation,用于存储type的注解对象】</li>
* <li>如果targetAnnotation为null,尝试从bd的工厂方法中获取targetAnnotation</li>
* <li>如果targetAnnotation为null,尝试从bd的合并后的RootBeanDefintion的工厂方法中获取targetAnnotation</li>
* <li>如果targetAnnotation为null,尝试从bean工厂中获取targetAnnotation</li>
* <li>如果targetAnnotation为null且bd已缓存了beanClass,尝试从bd的beanClass中获取targetAnnotation</li>
* <li>如果targetAnnotation不为null且targetAnnotation与annotation相等(会对注解里的属性也进行检查),
* 返回true,表示可以自动注入</li>
* </ol>
* </li>
* </ol>
* </li>
* <li>获取annotation的所有属性映射【变量 attributes】</li>
* <li>如果没有属性且没有qualifier,则返回false,表示不可自动注入;因为引用对象这时是有加上注解来限定的,
* 即使该注解没有属性,对应的bd也要有相应的qualifier标签约束才算匹配</li>
* <li>【<b>匹配所有两者的所有限定符属性</b>】:
* <ol>
* <li>遍历attributes:
* <ol>
* <li>获取属性名 【变量 attributeName】</li>
* <li>获取属性值,即引用对限定注解上所自定义的信息,可以理解为期望属性值 【变量 expectedValue】</li>
* <li>定义一个用于存储实际值的Object,即候选RootBeanDefinition对象的属性值【变量 actualValue】</li>
* <li>如果quanlifier不为null,actualValue尝试引用quanlifier的attributeNamed的属性值</li>
* <li>如果actualValue为null,actualValue尝试引用db的attributeName的属性值</li>
* <li>【单独处理属性名为value的情况】如果actualValue为null且属性名是'value'且期望值是String类型且期望值与bean名称或者
* expectedValue是bdHolder中存储的别名,就可以检查下一个属性【continue】</li>
* <li>如果actualValue为null且quanlifier不为null,actualValue尝试引用annotation的attributeName的默认值</li>
* <li>如果actualValue不为null,对actualValue进行类型转换,以对应上expectedValue类型</li>
* <li>如果actualValue与expecteValue不相等,返回false,表示不可以自动注入</li>
* </ol>
* </li>
* </ol>
* </li>
* <li>经过两者的所有属性的匹配都一致后,返回true,表示可以自动注入</li>
* </ol>
* </p>
* Match the given qualifier annotation against the candidate bean definition.
* <p>将给定的限定符注解与候选beanDefinition匹配</p>
* @param bdHolder – beanDefinition,包括bean名和别名封装对象
* @param annotation descriptor所包装的属性/方法参数的注解
* @param typeConverter 类型转换器
* @return 是否可以自动注入
*/
protected boolean checkQualifier(
BeanDefinitionHolder bdHolder, Annotation annotation, TypeConverter typeConverter) {
//获取annotation的注解类型
Class<? extends Annotation> type = annotation.annotationType();
//获取bdHolder的RootBeanDefinition对象
RootBeanDefinition bd = (RootBeanDefinition) bdHolder.getBeanDefinition();
//获取type在bd中限定符,即标签qualifier
AutowireCandidateQualifier qualifier = bd.getQualifier(type.getName());
//如果qualifier为null
if (qualifier == null) {
//ClassUtils.getShortName(type):获取type的短类名,即去掉了包名,且对内部类名会将$替换成.
//获取type短类名在bd中限定符
qualifier = bd.getQualifier(ClassUtils.getShortName(type));
}
//如果没有qualifier为null,表示没有配置标签qualifier,则优先通过@Quanlifier进行匹配
//如果qualifier为null
if (qualifier == null) {
// First, check annotation on qualified element, if any
// 首先,检查合格元素上的注解(如果有)
//从bd的bean注解信息中获取type的注释对象
Annotation targetAnnotation = getQualifiedElementAnnotation(bd, type);
// Then, check annotation on factory method, if applicable
// 然后,检查工厂方法的注解(如果可用)
// 尝试从bd的工厂方法中获取targetAnnotation
//如果targetAnnotation为null
if (targetAnnotation == null) {
//从bd的工厂方法中获取type的注解对象
targetAnnotation = getFactoryMethodAnnotation(bd, type);
}
// 尝试从bd的合并后的RootBeanDefintion的工厂方法中获取targetAnnotation
//如果targetAnnotation为null
if (targetAnnotation == null) {
//获取rbd所指bean名在beanFactory中的合并后RootBeanDefinition
RootBeanDefinition dbd = getResolvedDecoratedDefinition(bd);
//如果dbd不为null
if (dbd != null) {
//从dbd的工厂方法中获取type的注解对象
targetAnnotation = getFactoryMethodAnnotation(dbd, type);
}
}
//如果targetAnnotation为null
if (targetAnnotation == null) {
// Look for matching annotation on the target class
//在目标类上训阵匹配注释
// 尝试从bean工厂中获取targetAnnotation
//如果bean工厂不为null
if (getBeanFactory() != null) {
try {
//获取bdHolder指定的beanName在bean工厂中的Class对象
Class<?> beanType = getBeanFactory().getType(bdHolder.getBeanName());
//如果beanType不为null
if (beanType != null) {
//ClassUtils.getUserClass(beanType):如果beanType是CGLIB生成的子类,则返回该子类的父类,否则直接返回要检查的类
//从beanType中获取type的注解对象
targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(beanType), type);
}
}
//捕捉 没有此类BeanDefinition异常
catch (NoSuchBeanDefinitionException ex) {
// Not the usual case - simply forget about the type check...
//并非通常情况,只需忘记类型检查即可...
}
}
//尝试从bd的beanClass中获取targetAnnotation
//如果targetAnnotation为null且bd已缓存了beanClass
if (targetAnnotation == null && bd.hasBeanClass()) {
//从bd已缓存beanClass的中获取type的注解对象
targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(bd.getBeanClass()), type);
}
}
/**
* Annotation.equals:如果指定的对象表示在逻辑上等效于该注解的注解,则返回true。
* 换句话说,如果指定对象是与此实例具有相同注解类型的实例,并且其所有成员都与此
* 注解的对应的成员相同,则返回true,如下所示:
* 1.如果x==y,则两个分别为x和y的原始类型成员被视为相等,除非其类型为float或double.
* 2.如果Float.valueOf(x).equals(Float.valueOf(y)),则两个分别为x和y的相应float
* 成员被视为相等。(与==运算符不同,NaN被视为等于其自身,并且0.0f不等于-0.0f).
* 3.如果Double.valueOf(x).equals(Double.valueOf(y)),则两个分别为x和y的双精度成员
* 被视为相等.(与==运算符不同,NaN被视为等于其自身,并且0.0不等于-0.0)
* 4.如果x.equals(y),则将两个相应的String,Class,enumn或注释类型的成员(其值分辨为x和
* y)视为相等.(请注意,此定义对于注解类型的成员是递归的
* 5.如果Arrays.equals(x,y),则两个对应的数组类型成员x和y被视为相等,以适当重载
* java.util.Arrays.equals
*/
//如果targetAnnotation不为null且targetAnnotation与annotation相等(会对注解里的属性也进行检查)
if (targetAnnotation != null && targetAnnotation.equals(annotation)) {
return true;
}
}
//获取annotation的所有属性映射
Map<String, Object> attributes = AnnotationUtils.getAnnotationAttributes(annotation);
//如果没有属性且没有限定符
if (attributes.isEmpty() && qualifier == null) {
// If no attributes, the qualifier must be present
// 如果没有属性,则必须存在限定符
//返回false,表示不可自动注入;因为引用对象这时是有加上注解来限定的,即使该注解没有属性,对应的bd也要有相应的qualifier标签
// 约束才算匹配
return false;
}
//匹配所有两者的所有限定符属性,Spring认为只有两者的限定信息属性都一致的情况下,才是可以自动注入
//遍历属性映射
for (Map.Entry<String, Object> entry : attributes.entrySet()) {
//获取属性名
String attributeName = entry.getKey();
//获取属性值
Object expectedValue = entry.getValue();
//定义一个用于存储实际值的Object
Object actualValue = null;
// Check qualifier first
// 首先检查qualifier
//首先从db的限定符中对应的属性
//如果quanlifier不为null
if (qualifier != null) {
//引用quanlifier的attributeNamed的属性值
actualValue = qualifier.getAttribute(attributeName);
}
//尝试获取bd对应的属性
//如果actualValue为null
if (actualValue == null) {
// Fall back on bean definition attribute
// 回退beanDefinition属性值
//引用db的attributeName的属性值
actualValue = bd.getAttribute(attributeName);
}
//这里表示处理属性名为value的情况,Spring默认value属性只要是String类,都可以认为它用于匹配别名
//如果actualValue为null且属性名是'value'且期望值是String类型且期望值与bean名称或者
// expectedValue是bdHolder中存储的别名
if (actualValue == null && attributeName.equals(AutowireCandidateQualifier.VALUE_KEY) &&
expectedValue instanceof String && bdHolder.matchesName((String) expectedValue)) {
// Fall back on bean name (or alias) match
// 回退bean名称(或别名匹配)
// 既然与别名匹配,就可以检查下一个属性了,以后下面的操作不是针对value属性的。
//检查下一个属性
continue;
}
//处理在没有任何自定义设置该属性名的值的情况,可能是因为属性名有默认值。
//如果actualValue为null且quanlifier不为null
if (actualValue == null && qualifier != null) {
// Fall back on default, but only if the qualifier is present
// 回退到默认值,但前提是存在限定符
actualValue = AnnotationUtils.getDefaultValue(annotation, attributeName);
}
//对actualValue进行类型转换,以对应上expectedValue类型
//如果actualValue不为null
if (actualValue != null) {
actualValue = typeConverter.convertIfNecessary(actualValue, expectedValue.getClass());
}
//可能有会觉得这里actualValue会空指针,但是其实不会的,因为注解的属性在没有设置默认值的情况下,在使用的使用必须要
// 对该属性进行赋值,否则编译失败
//判断actualValue与expecteValue是否相等
//如果actualValue与expecteValue不相等,返回false,表示不可以自动注入
if (!expectedValue.equals(actualValue)) {
return false;
}
}
//经过两者的所有属性的匹配都一致后,返回true,表示可以自动注入
return true;
}
/**
* 从bd的QualifiedElement中获取type的注释对象
* @param bd bdHolder的RootBeanDefinition
* @param type 属于限定符的注解
* @return type的注释对象
*/
@Nullable
protected Annotation getQualifiedElementAnnotation(RootBeanDefinition bd, Class<? extends Annotation> type) {
//AnnotatedElement代表了在当前JVM中的一个“被注解元素”(可以是Class,Method,Field,Constructor,Package等)。
//RootBeanDefinition.getQualifiedElement:Bean的注解信息
//从bd中获取QualifiedElemnet
AnnotatedElement qualifiedElement = bd.getQualifiedElement();
//从qualifiedElement中获取type的注释对象,仅支持单级的元注解获取
return (qualifiedElement != null ? AnnotationUtils.getAnnotation(qualifiedElement, type) : null);
}
/**
* 从bd的工厂方法中获取type的注解对象
* @param bd bdHolder的RootBeanDefinition
* @param type 属于限定符的注解
* @return type的注释对象
*/
@Nullable
protected Annotation getFactoryMethodAnnotation(RootBeanDefinition bd, Class<? extends Annotation> type) {
//从bd中获取解析后的工厂方法作为java方法对象
Method resolvedFactoryMethod = bd.getResolvedFactoryMethod();
//从resolvedFactoryMethod中获取type的注释对象,仅支持单级的元注解获取
return (resolvedFactoryMethod != null ? AnnotationUtils.getAnnotation(resolvedFactoryMethod, type) : null);
}
/**
* <p>确定decriptor是否需要依赖项(检查descriptor是否设置了需要依赖项,descriptor的@Autowired注解信息):
* <ol>
* <li>如果父级确定descriptor不需要依赖项(descriptor是否设置了需要依赖项),返回false,表示不需要此依赖</li>
* <li>获取decriptor的Autowired注解对象【变量 autowired】</li>
* <li>如果没有配置@Autowired或者Autowired对象表明需要依赖项目,就返回true,表示需要依赖项;
* 否则返回false,表示不需要依赖项</li>
* </ol>
* </p>
* Determine whether the given dependency declares an autowired annotation,
* checking its required flag.
* <p>确定给定的依赖项是否声明了自动装配的注解,并且检查其必需标志</p>
* @see Autowired#required()
*/
@Override
public boolean isRequired(DependencyDescriptor descriptor) {
//如果父级确定descriptor不需要依赖项(descriptor是否设置了需要依赖项)。
if (!super.isRequired(descriptor)) {
//返回false,表示不需要此依赖
return false;
}
//获取decriptor的Autowired注解对象
Autowired autowired = descriptor.getAnnotation(Autowired.class);
//如果没有配置@Autowired或者Autowired对象表明需要依赖项目,就返回true,表示需要依赖项;
// 否则返回false,表示不需要依赖项
return (autowired == null || autowired.required());
}
/**
* Determine whether the given dependency declares a qualifier annotation.
* <p>确定给定的依赖项是否声明了限定符注解</p>
* @see #isQualifier(Class)
* @see Qualifier
*/
@Override
public boolean hasQualifier(DependencyDescriptor descriptor) {
//遍历decriptor的所有注解
for (Annotation ann : descriptor.getAnnotations()) {
//逐个判断ann的Class对象是否与qualifierTypes的某个元素相等
if (isQualifier(ann.annotationType())) {
//若相等,表示声明了限定符注解
return true;
}
}
//经过遍历,没发现限定符注解时,返回false表示没有声明限定符注解
return false;
}
/**
* <p>获取descriptor的@Value的value属性值:
* <ol>
* <li>从descriptor所包装的field/MethodParameter所有注解中获取@Value注解的value属性值【变量 value】</li>
* <li>如果value为null:
* <ol>
* <li>获取decriptor的方法参数对象 【变量 methodParam】</li>
* <li>如果有方法参数对象,从descriptor所包装的methodParameter的所属Method的所有注解中获取@Value注解的value属性值</li>
* </ol>
* </li>
* <li>返回@Value的属性值</li>
* </ol>
* </p>
* Determine whether the given dependency declares a value annotation.
* <p>确定给定的依赖项是否声明了@Value注解</p>
* @see Value
*/
@Override
@Nullable
public Object getSuggestedValue(DependencyDescriptor descriptor) {
//从descriptor所包装的field/MethodParameter所有注解中获取@Value注解的value属性值
Object value = findValue(descriptor.getAnnotations());
//如果value为null
if (value == null) {
//获取decriptor的方法参数对象
MethodParameter methodParam = descriptor.getMethodParameter();
//如果有方法参数对象
if (methodParam != null) {
//从descriptor所包装的methodParameter的所属Method的所有注解中获取@Value注解的value属性值
value = findValue(methodParam.getMethodAnnotations());
}
}
//返回@Value的属性值
return value;
}
/**
* <p>从annotationsToSearch中获取@Value注解的value属性值:
* <ol>
* <li>如果有注解:
* <ol>
* <li>通过annotationsToSearch得到合并后的注解属性,然后从合并后的注解属性中获取@Value注解的属性【变量 attr】</li>
* <li>如果注解属性不为null,从attr中获取value属性的属性值并返回出去</li>
* </ol>
* </li>
* <li>如果没有注解,或者没有配置@Value注解,默认返回null</li>
* </ol>
* </p>
* Determine a suggested value from any of the given candidate annotations.
* <p>从任何给定的候选注解中确定建议值</p>
* @param annotationsToSearch desciptor的field/methodParamater的所有注解
*/
@Nullable
protected Object findValue(Annotation[] annotationsToSearch) {
//如果有注解
if (annotationsToSearch.length > 0) { // qualifier annotations have to be local //限定符注释必须是本地的
//从合并后的注解属性中获取@Value注解的属性
AnnotationAttributes attr = AnnotatedElementUtils.getMergedAnnotationAttributes(
AnnotatedElementUtils.forAnnotations(annotationsToSearch), this.valueAnnotationType);
//如果注解属性不为null
if (attr != null) {
//从attr中获取value属性的属性值并返回出去
return extractValue(attr);
}
}
//如果没有注解,或者没有配置@Value注解,默认返回null
return null;
}
/**
* <p>从attr中获取value属性的属性值:
* <ol>
* <li>从注解属性中获取value的属性值【变量 value】</li>
* <li>如果value没有值,抛出非法状态异常:值注解必须居于属性值</li>
* <li>返回value的属性值</li>
* </ol>
* </p>
* Extract the value attribute from the given annotation.
* <p>从给定的注解中提取value属性</p>
* @since 4.3
*/
protected Object extractValue(AnnotationAttributes attr) {
//从注解属性中获取value的属性值
Object value = attr.get(AnnotationUtils.VALUE);
//如果value没有值
if (value == null) {
//抛出非法状态异常:值注解必须居于属性值
throw new IllegalStateException("Value annotation must have a value attribute");
}
//返回value的属性值
return value;
}
}
ContextAnnotationAutowireCandidateResolver
/**
* Complete implementation of the
* {@link org.springframework.beans.factory.support.AutowireCandidateResolver} strategy
* interface, providing support for qualifier annotations as well as for lazy resolution
* driven by the {@link Lazy} annotation in the {@code context.annotation} package.
* <p>{@link org.springframework.beans.factory.support.AutowireCandidateResolver}策略接口的
* 完整实现,提供对限定符注释以及由context.annoation包中的@Lazy注解驱动的延迟解析支持</p>
* @author Juergen Hoeller
* @since 4.0
*/
public class ContextAnnotationAutowireCandidateResolver extends QualifierAnnotationAutowireCandidateResolver {
/**
* 如有必要,获取惰性解析代理
* @param descriptor 目标方法参数或字段描述符
* @param beanName 包含注入点的bean名
* @return 实际依赖关系目标的惰性解决方案代理;如果要执行直接解决方案,则为null
*/
@Override
@Nullable
public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) {
//如果desciptor指定了懒加载,就会建立延迟解析代理对象然后返回出去,否则返回null
return (isLazy(descriptor) ? buildLazyResolutionProxy(descriptor, beanName) : null);
}
/**
* desciptor是否指定了懒加载:
* <ol>
* <li>【<b>检查decriptord所封装的Field/MethodParamater对象有没有@Lazy注解</b>】:
* <ol>
* <li>遍历decriptord的所有注解,元素为ann:
* <ol>
* <li>从an中取出@Lazy对象【变量 lazy】</li>
* <li>如果有lazy且lazy的值为true,就返回true,表示decriptor指定了懒加载</li>
* </ol>
* </li>
* </ol>
* </li>
* <li>【<b>检查decriptord所封装的MethodParamater对象所属的Method上有没有@Lazy注解</b>】:
* <ol>
* <li>从descriptor中获取方法参数【变量 methodParam】</li>
* <li>如果有方法参数
* <ol>
* <li>获取methodParam所属方法【变量 method】</li>
* <li>如果method是构造函数 或者 method是无返回值方法:
* <ol>
* <li>从methodParam所属的Method对象的注解中获取@Lazy注解对象</li>
* <li>如果有lazy且lazy的值为true,就返回true,表示decriptor指定了懒加载</li>
* </ol>
* </li>
* </ol>
* </li>
* </ol>
* </li>
* <li>如果descriptor所包含的对象没有加上@Lazy注解或者@Lazy没有指定成懒加载,就返回false,
* 表示没有指定了懒加载</li>
* </ol>
*/
protected boolean isLazy(DependencyDescriptor descriptor) {
//遍历decriptord的所有注解
for (Annotation ann : descriptor.getAnnotations()) {
//从an中取出@Lazy对象
Lazy lazy = AnnotationUtils.getAnnotation(ann, Lazy.class);
//如果有lazy且lazy的值为true,就返回true,表示decriptor指定了懒加载
if (lazy != null && lazy.value()) {
return true;
}
}
//从descriptor中获取方法参数
MethodParameter methodParam = descriptor.getMethodParameter();
//如果有方法参数
if (methodParam != null) {
//获取methodParam所属方法
Method method = methodParam.getMethod();
//method==null表示构造函数
//如果method是构造函数 或者 method是无返回值方法
if (method == null || void.class == method.getReturnType()) {
//从methodParam所属的Method对象的注解中获取@Lazy注解对象
Lazy lazy = AnnotationUtils.getAnnotation(methodParam.getAnnotatedElement(), Lazy.class);
//如果有lazy且lazy的值为true,就返回true,表示decriptor指定了懒加载
if (lazy != null && lazy.value()) {
return true;
}
}
}
//如果descriptor所包含的对象没有加上@Lazy注解或者@Lazy没有指定成懒加载,就返回false,表示没有指定了懒加载
return false;
}
/**
* 建立延迟解析代理:
* <ol>
* <li>如果bean工厂不是DefaultLisableBeanFactory的实例,抛出异常</li>
* <li>将bean工厂强转为DefaultLisableBeanFactory对象【变量 beanFactory】</li>
* <li>新建一个TargetSource对象,用于封装目标对象【变量 ts】:
* <ol>
* <li>getTargetClass():要返回的目标类型为descriptor的依赖类型</li>
* <li>isStatic():所有对getTarget()的调用都不需要返回相同的对象</li>
* <li>getTarget():
* <ol>
* <li>使用bean工厂解析出descriptor所指定的beanName的bean对象作为目标对象【变量 target】</li>
* <li>如果目标对象【target】为null:
* <ol>
* <li>获取目标对象的类型【变量 type】</li>
* <li>如果type是Mapp类型,返回空Map</li>
* <li>如果type为List类型,返回空List</li>
* <li>如果type为Set类型或者Collection类型</li>
* <li>其他情况抛出无此类BeanDefinition异常:延迟注入点不存在可依赖项</li>
* </ol>
* </li>
* <li>返回目标对象【target】</li>
* </ol>
* </li>
* <li>releaseTarget():空实现</li>
* </ol>
* </li>
* <li>新建一个代理工厂【{@link ProxyFactory}】对象【变量 pf】</li>
* <li>设置Pf的目标对象为ts</li>
* <li>获取desciptor所包装的对象的类型【变量 dependencyType】</li>
* <li>如果dependencyType是接口,设置pf的接口为dependencyType</li>
* <li>使用bean工厂的bean类加载器来使pf创建一下新的代理对象</li>
* </ol>
* @param descriptor 目标方法参数或字段描述符
* @param beanName 包含注入点的bean名
* @return 实际依赖关系目标的惰性解决方案代理;如果要执行直接解决方案,则为null
*/
protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, final @Nullable String beanName) {
//如果bean工厂不是DefaultLisableBeanFactory的实例,抛出异常
Assert.state(getBeanFactory() instanceof DefaultListableBeanFactory,
"BeanFactory needs to be a DefaultListableBeanFactory");
//将bean工厂强转为DefaultLisableBeanFactory对象
final DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) getBeanFactory();
//TargetSource:被代理的target(目标对象)实例的来源
// 新建一个TargetSource对象,用于封装目标对象
TargetSource ts = new TargetSource() {
@Override
public Class<?> getTargetClass() {
//要返回的目标类型为descriptor的依赖类型
return descriptor.getDependencyType();
}
@Override
public boolean isStatic() {
//所有对getTarget()的调用都不需要返回相同的对象
return false;
}
@Override
public Object getTarget() {
//使用bean工厂解析出descriptor所指定的beanName的bean对象作为目标对象
Object target = beanFactory.doResolveDependency(descriptor, beanName, null, null);
//如果目标对象为null
if (target == null) {
//获取目标对象的类型
Class<?> type = getTargetClass();
//如果目标对象是Mapp类型
if (Map.class == type) {
//返回空Map
return Collections.emptyMap();
}
//如果目标对象为List类型
else if (List.class == type) {
//返回空List
return Collections.emptyList();
}
//如果目标对象为Set类型或者Collection类型
else if (Set.class == type || Collection.class == type) {
//返回空Set
return Collections.emptySet();
}
//其他情况抛出无此类BeanDefinition异常:延迟注入点不存在可依赖项
throw new NoSuchBeanDefinitionException(descriptor.getResolvableType(),
"Optional dependency not present for lazy injection point");
}
//返回目标对象
return target;
}
@Override
public void releaseTarget(Object target) {
}
};
//ProxyFactory:用于AOP代理的工厂,以编程方式使用,而不是通过bean工厂中的声明性设置.此类提供了
// 一种在自定义用户代码中获取和配置AOP代理实例的简单方法
//新建一个代理工厂对象
ProxyFactory pf = new ProxyFactory();
//设置Pf的目标对象为ts
pf.setTargetSource(ts);
//获取desciptor所包装的对象的类型
Class<?> dependencyType = descriptor.getDependencyType();
//如果依赖类型是接口
if (dependencyType.isInterface()) {
//设置pf的接口为dependencyType
pf.addInterface(dependencyType);
}
//使用bean工厂的bean类加载器来使pf创建一下新的代理对象
return pf.getProxy(beanFactory.getBeanClassLoader());
}
}
版权声明:本文为qq_30321211原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。