11、Spring之Bean生命周期~依赖注入(2)

11、Spring之Bean生命周期~依赖注入(2)

  • 依赖注入
  • 查找注入点
  • 对注入点进行赋值
    • InjectionMetadata.inject()方法
    • AutowiredFieldElement.inject()方法
    • resolveFieldValue()方法
    • resolveDependency方法
    • createOptionalDependency()方法
    • doResolveDependency()方法
    • determineAutowireCandidate()方法
    • resolveMultipleBeans()方法
    • findAutowireCandidates()方法
    • beanNamesForTypeIncludingAncestors()方法
    • getBeanNamesForType()方法
    • doGetBeanNamesForType()方法
    • isTypeMatch()方法
    • @value注解解析
    • AutowiredMethodElement.inject()方法
    • resolveMethodArguments()方法
    • findAutowiringMetadata()方法
    • buildAutowiringMetadata()方法
    • findAutowiredAnnotation()方法
    • AutowiredAnnotationBeanPostProcessor构造器

依赖注入

这里我们重点解析AutowiredAnnotationBeanPostProcessor的源码,为什么要解析AutowiredAnnotationBeanPostProcessor呢,因为AutowiredAnnotationBeanPostProcessor的postProcessMergedBeanDefinition()方法中会寻找Bean对象的注入点,AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法中会给注入点赋值;接下来我们挨个分析。

查找注入点

postProcessMergedBeanDefinition()方法详解


/*** BeanDefinition的后置处理*/
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);metadata.checkConfigMembers(beanDefinition);
}

这里可以看到调用findAutowiringMetadata()方法寻找注入点;

对注入点进行赋值

postProcessProperties()方法详解

/*** 给注入点赋值*/@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {// 找注入点(所有被@Autowired注解了的Field或Method)// 因为在postProcessMergedBeanDefinition方法已经找到啦所有的注入点,这一步只是从缓存中获取所有的注入点InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);try {metadata.inject(bean, beanName, pvs);} catch (BeanCreationException ex) {throw ex;} catch (Throwable ex) {throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);}return pvs;
}

调用findAutowiringMetadata()方法到BeanName对应的所有注入点,调用InjectionMetadata.inject()方法;

InjectionMetadata.inject()方法

InjectionMetadata.inject()方法详解

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {Collection<InjectedElement> checkedElements = this.checkedElements;Collection<InjectedElement> elementsToIterate =(checkedElements != null ? checkedElements : this.injectedElements);if (!elementsToIterate.isEmpty()) {// 遍历每个注入点进行依赖注入for (InjectedElement element : elementsToIterate) {element.inject(target, beanName, pvs);}}
}

通过上述代码可以看到,如果注入点集合不是空,调用InjectedElement.inject()方法,因为InjectedElement是一个抽象类,有两个子类:AutowiredFieldElement和AutowiredMethodElement;

  • AutowiredFieldElement负责处理Field
    • AutowiredFieldElement.inject()方法
  • AutowiredMethodElement负责处理Method
    • AutowiredMethodElement.inject()方法

AutowiredFieldElement.inject()方法

AutowiredFieldElement.inject()方法详解


@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {Field field = (Field) this.member;Object value;if (this.cached) {// 对于原型Bean,第一次创建的时候,也找注入点,然后进行注入,此时cached为false,注入完了之后cached为true// 第二次创建的时候,先找注入点(此时会拿到缓存好的注入点),也就是AutowiredFieldElement对象,此时cache为true,也就进到此处了// 注入点内并没有缓存被注入的具体Bean对象,而是beanName,这样就能保证注入到不同的原型Bean对象try {value = resolvedCachedArgument(beanName, this.cachedFieldValue);} catch (NoSuchBeanDefinitionException ex) {// Unexpected removal of target bean for cached argument -> re-resolvevalue = resolveFieldValue(field, bean, beanName);}} else {// 根据filed从BeanFactory中查到的匹配的Bean对象value = resolveFieldValue(field, bean, beanName);}// 反射给filed赋值if (value != null) {ReflectionUtils.makeAccessible(field);field.set(bean, value);}
}

通过上述代码我们可以看到这里大概分三步:

  1. 判断是否有缓存;如果有缓存调用resolvedCachedArgument()方法;
  2. 没缓存调用resolveFieldValue()方法;
  3. 最后反射赋值;

返回InjectionMetadata.inject()方法;

resolveFieldValue()方法

resolveFieldValue()方法详解

@Nullable
private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {DependencyDescriptor desc = new DependencyDescriptor(field, this.required);desc.setContainingClass(bean.getClass());Set<String> autowiredBeanNames = new LinkedHashSet<>(1);Assert.state(beanFactory != null, "No BeanFactory available");TypeConverter typeConverter = beanFactory.getTypeConverter();Object value;try {value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);} catch (BeansException ex) {throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);}synchronized (this) {if (!this.cached) {Object cachedFieldValue = null;if (value != null || this.required) {cachedFieldValue = desc;// 注册一下beanName依赖了autowiredBeanNames,registerDependentBeans(beanName, autowiredBeanNames);if (autowiredBeanNames.size() == 1) {String autowiredBeanName = autowiredBeanNames.iterator().next();if (beanFactory.containsBean(autowiredBeanName) &&beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {// 构造一个ShortcutDependencyDescriptor作为缓存,保存了当前filed所匹配的autowiredBeanName,而不是对应的bean对象(考虑原型bean)cachedFieldValue = new ShortcutDependencyDescriptor(desc, autowiredBeanName, field.getType());}}}this.cachedFieldValue = cachedFieldValue;this.cached = true;}}return value;
}

通过上述代码我们可以看到:

  1. 首先创建DependencyDescriptor对象;
  2. 经过一系列判断之后,调用AutowireCapableBeanFactory的resolveDependency方法,因为DefaultListableBeanFactory实现啦AutowireCapableBeanFactory接口,最终会走到DefaultListableBeanFactory的resolveDependency()方法;
  3. 找到要注入的Bean对象之后会调用registerDependentBeans()方法,记录依赖关系;

返回AutowiredFieldElement.inject()方法;

resolveDependency方法

resolveDependency()方法详解

@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {// 用来获取方法入参名字的descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());// 所需要的类型是Optionalif (Optional.class == descriptor.getDependencyType()) {return createOptionalDependency(descriptor, requestingBeanName);}// 所需要的的类型是ObjectFactory,或ObjectProviderelse if (ObjectFactory.class == descriptor.getDependencyType() ||ObjectProvider.class == descriptor.getDependencyType()) {return new DependencyObjectProvider(descriptor, requestingBeanName);} else if (javaxInjectProviderClass == descriptor.getDependencyType()) {return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);} else {// 在属性或set方法上使用了@Lazy注解,那么则构造一个代理对象并返回,真正使用该代理对象时才进行类型筛选BeanObject result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);if (result == null) {// descriptor表示某个属性或某个set方法// requestingBeanName表示正在进行依赖注入的Beanresult = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);}return result;}
}

这里我们看到的是DefaultListableBeanFactory类的resolveDependency()方法:

  1. 如果现在方法参数不是null,初始化ParameterNameDiscoverer对象;
  2. 如果需要的类型是Optional,会调用createOptionalDependency()方法,其实还是调用doResolveDependency()方法,只是将返回值封装成Optional类型;
  3. 如果需要的类型是ObjectFactory或者是ObjectProvider,会创建DependencyObjectProvider对象返回;
  4. 如果需要的类型是javaxInjectProviderClass,会创建Jsr330Provider对象返回;
  5. 再往下我们看到,如果属性或者方法上有@Lazy注解会创建代理对象;
  6. 如果代理对象是null,调用doResolveDependency()方法;

返回resolveFieldValue()方法;
返回resolveMethodArguments()方法;

createOptionalDependency()方法

createOptionalDependency()方法详解

/*** Create an {@link Optional} wrapper for the specified dependency.*/
private Optional<?> createOptionalDependency(DependencyDescriptor descriptor, @Nullable String beanName, final Object... args) {DependencyDescriptor descriptorToUse = new NestedDependencyDescriptor(descriptor) {@Overridepublic boolean isRequired() {return false;}@Overridepublic Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) {return (!ObjectUtils.isEmpty(args) ? beanFactory.getBean(beanName, args) :super.resolveCandidate(beanName, requiredType, beanFactory));}};Object result = doResolveDependency(descriptorToUse, beanName, null, null);return (result instanceof Optional ? (Optional<?>) result : Optional.ofNullable(result));
}

通过上述代码我么可以看到,会调用doResolveDependency()方法,将返回值封装成Optional类型;

返回resolveDependency()方法;

doResolveDependency()方法

doResolveDependency()方法详解

@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);try {// 如果当前descriptor之前做过依赖注入了,则可以直接取shortcut了,相当于缓存Object shortcut = descriptor.resolveShortcut(this);if (shortcut != null) {return shortcut;}Class<?> type = descriptor.getDependencyType();// 获取@Value所指定的值Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);if (value != null) {if (value instanceof String) {// 占位符填充(${})String strVal = resolveEmbeddedValue((String) value);BeanDefinition bd = (beanName != null && containsBean(beanName) ?getMergedBeanDefinition(beanName) : null);// 解析Spring表达式(#{})value = evaluateBeanDefinitionString(strVal, bd);}// 将value转化为descriptor所对应的类型TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());try {return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());} catch (UnsupportedOperationException ex) {// A custom TypeConverter which does not support TypeDescriptor resolution...return (descriptor.getField() != null ?converter.convertIfNecessary(value, type, descriptor.getField()) :converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));}}// 如果descriptor所对应的类型是数组、Map这些,就将descriptor对应的类型所匹配的所有bean方法,不用进一步做筛选了Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);if (multipleBeans != null) {return multipleBeans;}// 找到所有Bean,key是beanName, value有可能是bean对象,有可能是beanClassMap<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);if (matchingBeans.isEmpty()) {// required为true,抛异常if (isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);}return null;}String autowiredBeanName;Object instanceCandidate;if (matchingBeans.size() > 1) {// 根据类型找到了多个Bean,进一步筛选出某一个, @Primary-->优先级最高--->nameautowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);if (autowiredBeanName == null) {if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);} else {// In case of an optional Collection/Map, silently ignore a non-unique case:// possibly it was meant to be an empty collection of multiple regular beans// (before 4.3 in particular when we didn't even look for collection beans).return null;}}instanceCandidate = matchingBeans.get(autowiredBeanName);} else {// We have exactly one match.Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();autowiredBeanName = entry.getKey();instanceCandidate = entry.getValue();}// 记录匹配过的beanNameif (autowiredBeanNames != null) {autowiredBeanNames.add(autowiredBeanName);}// 有可能筛选出来的是某个bean的类型,此处就进行实例化,调用getBeanif (instanceCandidate instanceof Class) {instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);}Object result = instanceCandidate;if (result instanceof NullBean) {if (isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);}result = null;}if (!ClassUtils.isAssignableValue(type, result)) {throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());}return result;} finally {ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);}
}

通过上述代码我们可以看到:

  1. 首先会判断当前属性的依赖关系是否有值,有值说明之前做过依赖注入,直接用之前找到的值,不用再次查找,起到缓存的作用;
  2. 如果有@value注解,对@value注解解析,拿到返回值直接返回;
  3. 调用resolveMultipleBeans()方法,主要逻辑:如果需要注入的类型的是:Stream、Array、Collection或Map,将descriptor类型所匹配的所有bean对象封装成Stream、Array、Collection或Map,进行返回;
  4. 调用findAutowireCandidates()方法查找类型对象的Bean对象或者BeanClass;
  5. 如果查找的对象是0,且required为true,会报错,required不是true,返回null;
  6. 如果查找的对象大于1,有多个,调用determineAutowireCandidate()方法确认具体是哪一个;
  7. 如果查找的对象只有一个;
  8. 记录依赖关系,这个类型和哪些BeanName能匹配上;
  9. 如果查找到的对象还没有进行实例化,进行实例化操作;
  10. 判断找到的对象是否是NullBean,如果是NullBean且required属性是true,会报错;

在这个方法最后有一个finally代码块,这里先标记一下,这里是解决循环依赖的一部分代码;

返回createOptionalDependency()方法;
返回resolveDependency()方法;

determineAutowireCandidate()方法

determineAutowireCandidate()方法详解

/*** Determine the autowire candidate in the given set of beans.* <p>Looks for {@code @Primary} and {@code @Priority} (in that order).** @param candidates a Map of candidate names and candidate instances*                   that match the required type, as returned by {@link #findAutowireCandidates}* @param descriptor the target dependency to match against* @return the name of the autowire candidate, or {@code null} if none found*/
@Nullable
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {Class<?> requiredType = descriptor.getDependencyType();// candidates表示根据类型所找到的多个Bean,判断这些Bean中是否有一个是@Primary的String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);if (primaryCandidate != null) {return primaryCandidate;}// 取优先级最高的BeanString priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);if (priorityCandidate != null) {return priorityCandidate;}logger.info("byName赋值逻辑===开始");// Fallback// 匹配descriptor的名字,要么是字段的名字,要么是set方法入参的名字for (Map.Entry<String, Object> entry : candidates.entrySet()) {String candidateName = entry.getKey();Object beanInstance = entry.getValue();// resolvableDependencies记录了某个类型对应某个Bean,启动Spring时会进行设置,比如BeanFactory.class对应BeanFactory实例// 注意:如果是Spring自己的byType,descriptor.getDependencyName()将返回空,只有是@Autowired才会方法属性名或方法参数名if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||matchesBeanName(candidateName, descriptor.getDependencyName())) {logger.info("byName赋值逻辑===结束");return candidateName;}}return null;
}

通过上述代码,我们可以看到:

  1. 首先会调用determinePrimaryCandidate()方法,遍历所有符合要求的Bean对象,这些Bean对象有一个有@Primary注解,返回这个有@Primary注解的Bean对象,如果有多个Bean对象都有@Primary注解,会报错;
  2. 然后调用determineHighestPriorityCandidate()方法,遍历Bean上是否有@Priority注解,如果有取优先级最高的Bean对象(数字越小优先级越高),通过如果有多个@Priority注解的值是一样的,会报错;
  3. 最后遍历所有符合要求的Bean对象,根据BeanName匹配;

返回doResolveDependency()方法;

resolveMultipleBeans()方法

resolveMultipleBeans()方法详解

@Nullable
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {Class<?> type = descriptor.getDependencyType();if (descriptor instanceof StreamDependencyDescriptor) {// 找到type所匹配的所有beanMap<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);if (autowiredBeanNames != null) {autowiredBeanNames.addAll(matchingBeans.keySet());}// 构造成一个streamStream<Object> stream = matchingBeans.keySet().stream().map(name -> descriptor.resolveCandidate(name, type, this)).filter(bean -> !(bean instanceof NullBean));// 排序if (((StreamDependencyDescriptor) descriptor).isOrdered()) {stream = stream.sorted(adaptOrderComparator(matchingBeans));}return stream;} else if (type.isArray()) {// 得到数组元素的类型Class<?> componentType = type.getComponentType();ResolvableType resolvableType = descriptor.getResolvableType();Class<?> resolvedArrayType = resolvableType.resolve(type);if (resolvedArrayType != type) {componentType = resolvableType.getComponentType().resolve();}if (componentType == null) {return null;}// 根据数组元素类型找到所匹配的所有BeanMap<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,new MultiElementDescriptor(descriptor));if (matchingBeans.isEmpty()) {return null;}if (autowiredBeanNames != null) {autowiredBeanNames.addAll(matchingBeans.keySet());}// 进行类型转化TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType);if (result instanceof Object[]) {Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);if (comparator != null) {Arrays.sort((Object[]) result, comparator);}}return result;} else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();if (elementType == null) {return null;}Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,new MultiElementDescriptor(descriptor));if (matchingBeans.isEmpty()) {return null;}if (autowiredBeanNames != null) {autowiredBeanNames.addAll(matchingBeans.keySet());}TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());Object result = converter.convertIfNecessary(matchingBeans.values(), type);if (result instanceof List) {if (((List<?>) result).size() > 1) {Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);if (comparator != null) {((List<?>) result).sort(comparator);}}}return result;} else if (Map.class == type) {ResolvableType mapType = descriptor.getResolvableType().asMap();Class<?> keyType = mapType.resolveGeneric(0);// 如果Map的key不是Stringif (String.class != keyType) {return null;}Class<?> valueType = mapType.resolveGeneric(1);if (valueType == null) {return null;}Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,new MultiElementDescriptor(descriptor));if (matchingBeans.isEmpty()) {return null;}if (autowiredBeanNames != null) {autowiredBeanNames.addAll(matchingBeans.keySet());}return matchingBeans;} else {return null;}
}

通过上述代码可以看到:
  对属性类型依次进行Stream、Array、Collection、Map判断,然后调用findAutowireCandidates()方法查询类型对应的Bean对象信息,拿到所有的Bean对象,将其封装成属性对应的类型;

返回doResolveDependency()方法;

findAutowireCandidates()方法

findAutowireCandidates()方法详解

/*** Find bean instances that match the required type.* Called during autowiring for the specified bean.** @param beanName     the name of the bean that is about to be wired* @param requiredType the actual type of bean to look for*                     (may be an array component type or collection element type)* @param descriptor   the descriptor of the dependency to resolve* @return a Map of candidate names and candidate instances that match* the required type (never {@code null})* @throws BeansException in case of errors* @see #autowireByType* @see #autowireConstructor*/
protected Map<String, Object> findAutowireCandidates(@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {// 从BeanFactory中找出和requiredType所匹配的beanName,仅仅是beanName,这些bean不一定经过了实例化,只有到最终确定某个Bean了,如果这个Bean还没有实例化才会真正进行实例化String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType, true, descriptor.isEager());Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);// 根据类型从resolvableDependencies中匹配Bean,resolvableDependencies中存放的是类型:Bean对象,比如BeanFactory.class:BeanFactory对象,在Spring启动时设置for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {Class<?> autowiringType = classObjectEntry.getKey();if (autowiringType.isAssignableFrom(requiredType)) {Object autowiringValue = classObjectEntry.getValue();autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);if (requiredType.isInstance(autowiringValue)) {result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);break;}}}for (String candidate : candidateNames) {// 如果不是自己,则判断该candidate到底能不能用来进行自动注入if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {addCandidateEntry(result, candidate, descriptor, requiredType);}}// 为空要么是真的没有匹配的,要么是匹配的自己if (result.isEmpty()) {// 需要匹配的类型是不是Map、数组之类的boolean multiple = indicatesMultipleBeans(requiredType);// Consider fallback matches if the first pass failed to find anything...DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();for (String candidate : candidateNames) {if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {addCandidateEntry(result, candidate, descriptor, requiredType);}}// 匹配的是自己,被自己添加到result中if (result.isEmpty() && !multiple) {// Consider self references as a final pass...// but in the case of a dependency collection, not the very same bean itself.for (String candidate : candidateNames) {if (isSelfReference(beanName, candidate) &&(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&isAutowireCandidate(candidate, fallbackDescriptor)) {addCandidateEntry(result, candidate, descriptor, requiredType);}}}}return result;
}

通过上述代码我们可以看到:

  1. 首先调用BeanFactoryUtils.beanNamesForTypeIncludingAncestors()方法查找属性类型对应的BeanName,为什么是BeanName,因为bean不一定经过了实例化,只有到最终确定某个Bean了,如果这个Bean还没有实例化才会真正进行实例化;
  2. 再往下还会去查找resolvableDependencies中key为是这个类型的对象找出来并添加到result中;
  3. 再往下会循环通过BeanFactoryUtils.beanNamesForTypeIncludingAncestors()方法查找到的BeanName;
  4. 首先调用isSelfReference()方法判断当前Bean对象和要注入的Bean是不是一个Bean;
  5. 如果是自己直接跳过,如果不是自己还会调用isAutowireCandidate()方法判断,这个Bean是否可以进行依赖注入,比如@Bean(autowireCandidate = false),表示这个Bean是不能注入给其他Bean的;
  6. 如果两个判断通过调用addCandidateEntry()方法,将Bean对象放入result集合中;
  7. 判断result集合是否为空,不为空直接返回;
  8. 为空,进入下面判断逻辑;
  9. 第一块逻辑其实是校验要注入的对象是不是Arra、Collection或者Map之类的,还是会将自己排除掉,然后判断Bean是否可以进行依赖注入,有@Qualifier注解的话,判断@Qualifier注解是否满足条件;
  10. 如果还是没有满足结果的Bean对象,说明要自己注入自己,再判断Bean是否可以进行依赖注入,满足条件将自己放入result集合中;

返回resolveMultipleBeans()方法;
返回doResolveDependency()方法;

beanNamesForTypeIncludingAncestors()方法

beanNamesForTypeIncludingAncestors()方法详解

/*** Get all bean names for the given type, including those defined in ancestor* factories. Will return unique names in case of overridden bean definitions.* <p>Does consider objects created by FactoryBeans if the "allowEagerInit"* flag is set, which means that FactoryBeans will get initialized. If the* object created by the FactoryBean doesn't match, the raw FactoryBean itself* will be matched against the type. If "allowEagerInit" is not set,* only raw FactoryBeans will be checked (which doesn't require initialization* of each FactoryBean).* @param lbf the bean factory* @param includeNonSingletons whether to include prototype or scoped beans too* or just singletons (also applies to FactoryBeans)* @param allowEagerInit whether to initialize <i>lazy-init singletons</i> and* <i>objects created by FactoryBeans</i> (or by factory methods with a* "factory-bean" reference) for the type check. Note that FactoryBeans need to be* eagerly initialized to determine their type: So be aware that passing in "true"* for this flag will initialize FactoryBeans and "factory-bean" references.* @param type the type that beans must match* @return the array of matching bean names, or an empty array if none* @see ListableBeanFactory#getBeanNamesForType(Class, boolean, boolean)*/
public static String[] beanNamesForTypeIncludingAncestors(ListableBeanFactory lbf, Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {Assert.notNull(lbf, "ListableBeanFactory must not be null");// 从本容器中找String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);// 从父容器找并放入resultif (lbf instanceof HierarchicalBeanFactory) {HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {String[] parentResult = beanNamesForTypeIncludingAncestors((ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);result = mergeNamesWithParent(result, parentResult, hbf);}}return result;
}

  通过上述代码,我们可以看到,这个方法是一个递归,先从当前BeanFactory中查找,再从父BeanFactory中查找,最后将所有的BeanName放入String数组中,这里没有做去重;

  1. 首先会调用ListableBeanFactory接口的getBeanNamesForType()方法,因为findAutowireCandidates()方法在调用beanNamesForTypeIncludingAncestors()方法时,第一个参数传的是this,所以这里的getBeanNamesForType()方法会走到DefaultListableBeanFactory类的getBeanNamesForType()方法;

返回findAutowireCandidates()方法;

getBeanNamesForType()方法

getBeanNamesForType()方法详解

@Override
public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {// 如果没有冻结,就根据类型去BeanFactory找,如果冻结了,可能就跳过这个if然后去缓存中去拿了if (!isConfigurationFrozen() || type == null || !allowEagerInit) {return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);}// 把当前类型所匹配的beanName缓存起来Map<Class<?>, String[]> cache =(includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);String[] resolvedBeanNames = cache.get(type);if (resolvedBeanNames != null) {return resolvedBeanNames;}resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {cache.put(type, resolvedBeanNames);}return resolvedBeanNames;
}

通过上述段我们可以看到,这里核心是调用doGetBeanNamesForType()方法;

返回BeanFactoryUtils.beanNamesForTypeIncludingAncestors()方法;

doGetBeanNamesForType()方法

doGetBeanNamesForType()方法详解

private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {List<String> result = new ArrayList<>();// Check all bean definitions.// 遍历所有的BeanNamefor (String beanName : this.beanDefinitionNames) {// Only consider bean as eligible if the bean name is not defined as alias for some other bean.if (!isAlias(beanName)) {try {RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);// Only check bean definition if it is complete.// 判断mbd允不允许获取对应类型// 首先mdb不能是抽象的,然后allowEagerInit为true,则直接去推测mdb的类型,并进行匹配// 如果allowEagerInit为false,那就继续判断,如果mdb还没有加载类并且是懒加载的并且不允许提前加载类,那mbd不能用来进行匹配(因为不允许提前加载类,只能在此mdb自己去创建bean对象时才能去创建类)// 如果allowEagerInit为false,并且mbd已经加载类了,或者是非懒加载的,或者允许提前加载类,并且不用必须提前初始化才能获取类型,那么就可以去进行匹配了// 这个条件有点复杂,但是如果只考虑大部分流程,则可以忽略这个判断,因为allowEagerInit传进来的基本上都是trueif (!mbd.isAbstract() && (allowEagerInit ||(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&!requiresEagerInitForType(mbd.getFactoryBeanName()))) {boolean isFactoryBean = isFactoryBean(beanName, mbd);BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();boolean matchFound = false;boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton(beanName));boolean isNonLazyDecorated = (dbd != null && !mbd.isLazyInit());// 当前BeanDefinition不是FactoryBean,就是普通Beanif (!isFactoryBean) {// 在筛选Bean时,如果仅仅只包括单例,但是beanName对应的又不是单例,则忽略if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);}} else {if (includeNonSingletons || isNonLazyDecorated ||(allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);}if (!matchFound) {// In case of FactoryBean, try to match FactoryBean instance itself next.beanName = FACTORY_BEAN_PREFIX + beanName;matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);}}if (matchFound) {result.add(beanName);}}} catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {if (allowEagerInit) {throw ex;}// Probably a placeholder: let's ignore it for type matching purposes.LogMessage message = (ex instanceof CannotLoadBeanClassException ?LogMessage.format("Ignoring bean class loading failure for bean '%s'", beanName) :LogMessage.format("Ignoring unresolvable metadata in bean definition '%s'", beanName));logger.trace(message, ex);// Register exception, in case the bean was accidentally unresolvable.onSuppressedException(ex);} catch (NoSuchBeanDefinitionException ex) {// Bean definition got removed while we were iterating -> ignore.}}}// Check manually registered singletons too.for (String beanName : this.manualSingletonNames) {try {// In case of FactoryBean, match object created by FactoryBean.if (isFactoryBean(beanName)) {if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {result.add(beanName);// Match found for this bean: do not match FactoryBean itself anymore.continue;}// In case of FactoryBean, try to match FactoryBean itself next.beanName = FACTORY_BEAN_PREFIX + beanName;}// Match raw bean instance (might be raw FactoryBean).if (isTypeMatch(beanName, type)) {result.add(beanName);}} catch (NoSuchBeanDefinitionException ex) {// Shouldn't happen - probably a result of circular reference resolution...logger.trace(LogMessage.format("Failed to check manually registered singleton with name '%s'", beanName), ex);}}return StringUtils.toStringArray(result);
}

通过上述代码我们可以看到:

  1. 循环所有的BeanName;
  2. 判断当前BeanName不是别名;
  3. 通过BeanName拿到合并后的BeanDefinition(可以直接创建Bean对象的BeanDefinition);
  4. 首先BeanDefinition不能是抽象的;
  5. 如果allowEagerInit为true,则直接去推测BeanDefinition的类型,并进行匹配;
  6. 如果allowEagerInit为false,那就继续判断,如果BeanDefinition还没有加载类并且是懒加载的并且不允许提前加载类,那BeanDefinition不能用来进行匹配(因为不允许提前加载类,只能在BeanDefinition自己去创建bean对象时才能去创建类)
  7. 如果allowEagerInit为false,并且BeanDefinition已经加载类了,或者是非懒加载的,或者允许提前加载类,并且不用必须提前初始化才能获取类型,那么就可以去进行匹配了;
  8. 不管是不是FactoryBean都会调用isTypeMatch()方法,只是传参不同;
  9. 根据isTypeMatch()方法的返回值判断BeanName是否需要放入集合中;
  10. 再往下这个循环,通过注释“Check manually registered singletons too.”,我们可以得知,这里是校验不是通过扫描得到的Bean对象;符合要求也会放入集合中;

返回getBeanNamesForType()方法;

isTypeMatch()方法

isTypeMatch()方法详解

/*** Internal extended variant of {@link #isTypeMatch(String, ResolvableType)}* to check whether the bean with the given name matches the specified type. Allow* additional constraints to be applied to ensure that beans are not created early.** @param name        the name of the bean to query* @param typeToMatch the type to match against (as a*                    {@code ResolvableType})* @return {@code true} if the bean type matches, {@code false} if it* doesn't match or cannot be determined yet* @throws NoSuchBeanDefinitionException if there is no bean with the given name* @see #getBean* @see #getType* @since 5.2*/
protected boolean isTypeMatch(String name, ResolvableType typeToMatch, boolean allowFactoryBeanInit)throws NoSuchBeanDefinitionException {// 判断name所对应的Bean的类型是不是typeToMatch// allowFactoryBeanInit表示允不允许在这里实例化FactoryBean对象// 如果name是&xxx,那么beanName就是xxxString beanName = transformedBeanName(name);// name是不是&xxxboolean isFactoryDereference = BeanFactoryUtils.isFactoryDereference(name);// Check manually registered singletons.Object beanInstance = getSingleton(beanName, false);if (beanInstance != null && beanInstance.getClass() != NullBean.class) {if (beanInstance instanceof FactoryBean) {if (!isFactoryDereference) {// 调用factoryBean.getObjectType()Class<?> type = getTypeForFactoryBean((FactoryBean<?>) beanInstance);return (type != null && typeToMatch.isAssignableFrom(type));} else {return typeToMatch.isInstance(beanInstance);}} else if (!isFactoryDereference) {  // 不是FactoryBean,就是普通Bean// 直接匹配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));}}return false;} else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) {// null instance registeredreturn false;}// No singleton instance found -> check bean definition.BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// No bean definition found in this factory -> delegate to parent.return parentBeanFactory.isTypeMatch(originalBeanName(name), typeToMatch);}// 单例池中没有name对应的Bean对象,就只能根据BeanDefinition来判断出类型了// Retrieve corresponding bean definition.RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();// Setup the types that we want to match againstClass<?> classToMatch = typeToMatch.resolve();if (classToMatch == null) {classToMatch = FactoryBean.class;}// 为了判断当前beanName,是不是classToMatch或FactoryBeanClass<?>[] typesToMatch = (FactoryBean.class == classToMatch ?new Class<?>[]{classToMatch} : new Class<?>[]{FactoryBean.class, classToMatch});// Attempt to predict the bean typeClass<?> predictedType = null;// We're looking for a regular reference but we're a factory bean that has// a decorated bean definition. The target bean should be the same type// as FactoryBean would ultimately return. 啃if (!isFactoryDereference && dbd != null && isFactoryBean(beanName, mbd)) {// We should only attempt if the user explicitly set lazy-init to true// and we know the merged bean definition is for a factory bean.if (!mbd.isLazyInit() || allowFactoryBeanInit) {RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);// getObjectType所方法的类型Class<?> targetType = predictBeanType(dbd.getBeanName(), tbd, typesToMatch);if (targetType != null && !FactoryBean.class.isAssignableFrom(targetType)) {predictedType = targetType;}}}// If we couldn't use the target type, try regular prediction.if (predictedType == null) {predictedType = predictBeanType(beanName, mbd, typesToMatch);if (predictedType == null) {return false;}}// Attempt to get the actual ResolvableType for the bean.ResolvableType beanType = null;// If it's a FactoryBean, we want to look at what it creates, not the factory class.// BeanDefinition的类型是不是FactoryBean,如果是得先实例化FactoryBean这个对象,然后调用getObjectType方法才能知道具体的类型,前提是allowFactoryBeanInit为trueif (FactoryBean.class.isAssignableFrom(predictedType)) {if (beanInstance == null && !isFactoryDereference) {beanType = getTypeForFactoryBean(beanName, mbd, allowFactoryBeanInit);predictedType = beanType.resolve();if (predictedType == null) {return false;}}} else if (isFactoryDereference) {// Special case: A SmartInstantiationAwareBeanPostProcessor returned a non-FactoryBean// type but we nevertheless are being asked to dereference a FactoryBean...// Let's check the original bean class and proceed with it if it is a FactoryBean.predictedType = predictBeanType(beanName, mbd, FactoryBean.class);if (predictedType == null || !FactoryBean.class.isAssignableFrom(predictedType)) {return false;}}// We don't have an exact type but if bean definition target type or the factory// method return type matches the predicted type then we can use that.if (beanType == null) {ResolvableType definedType = mbd.targetType;if (definedType == null) {definedType = mbd.factoryMethodReturnType;}if (definedType != null && definedType.resolve() == predictedType) {beanType = definedType;}}// If we have a bean type use it so that generics are consideredif (beanType != null) {return typeToMatch.isAssignableFrom(beanType);}// If we don't have a bean type, fallback to the predicted typereturn typeToMatch.isAssignableFrom(predictedType);
}

通过上述代码我们可以看到:

  1. 首先调用transformedBeanName()方法拿到真正的BeanName;
  2. 判断当前Bean是否是FactoryBean;
  3. 调用getSingleton()方法从单例池中获取Bean对象;
  4. 如果单例池中Bean对象不是null且不是NullBean,再判断是否是FactoryBean;
  5. 如果是FactoryBean,根据传进来的BeanName判断是找那个对象,&xxx调用getObjectType()方法拿到类型进行判断,xxx直接获取Bean对象进行类型匹配;
  6. 不是FactoryBean就是普通Bean对象,直接拿Bean对象进行类型匹配;
  7. 如果单例池中Bean对象不存在;判断单例池中包含这个BeanName且BeanDefinition不包含这个BeanName,说明类型没有匹配成功;
  8. 再往下由于逻辑过于繁琐,外加本篇篇幅确实太长,这个说一下大概逻辑:
  9. 从BeanDefinition中拿到类型去判断,再判断是否是FactoryBean,…… ,总之,匹配到返回true,匹配不到返回false;

返回doGetBeanNamesForType()方法;

@value注解解析

@value注解解析

// 获取@Value所指定的值
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {if (value instanceof String) {// 占位符填充(${})String strVal = resolveEmbeddedValue((String) value);BeanDefinition bd = (beanName != null && containsBean(beanName) ?getMergedBeanDefinition(beanName) : null);// 解析Spring表达式(#{})value = evaluateBeanDefinitionString(strVal, bd);}// 将value转化为descriptor所对应的类型TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());try {return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());} catch (UnsupportedOperationException ex) {// A custom TypeConverter which does not support TypeDescriptor resolution...return (descriptor.getField() != null ?converter.convertIfNecessary(value, type, descriptor.getField()) :converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));}
}

上述代码片段来自doResolveDependency()方法,我们可以看到:

  1. 如果有@value注解,值是字符串类型,
  2. 调用resolveEmbeddedValue()方法进行占位符解析,解析@value(“${xxx}”);
  3. 拿到占位符解析结果之后在调用evaluateBeanDefinitionString()方法,进行spring表达式解析,解析@value(“#{xxx}”);
  4. 最后将解析出来的值转换成属性对应的类型,进行返回;

返回doResolveDependency()方法;

AutowiredMethodElement.inject()方法

AutowiredMethodElement.inject()方法详解

@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {// 如果pvs中已经有当前注入点的值了,则跳过注入if (checkPropertySkipping(pvs)) {return;}Method method = (Method) this.member;Object[] arguments;if (this.cached) {try {arguments = resolveCachedArguments(beanName);} catch (NoSuchBeanDefinitionException ex) {// Unexpected removal of target bean for cached argument -> re-resolvearguments = resolveMethodArguments(method, bean, beanName);}} else {arguments = resolveMethodArguments(method, bean, beanName);}if (arguments != null) {try {ReflectionUtils.makeAccessible(method);method.invoke(bean, arguments);} catch (InvocationTargetException ex) {throw ex.getTargetException();}}
}

这里我们可以看到:

  1. 首先调用checkPropertySkipping()方法,如果在之前已经对当前注入点设置啦值,则跳过注入;(比如:实例化后等)
  2. 如果有缓存,调用resolveCachedArguments()方法,查找缓存;
  3. 没有缓存,调用resolveMethodArguments()方法;

返回InjectionMetadata.inject()方法;

resolveMethodArguments()方法

resolveMethodArguments()方法详解

@Nullable
private Object[] resolveMethodArguments(Method method, Object bean, @Nullable String beanName) {int argumentCount = method.getParameterCount();Object[] arguments = new Object[argumentCount];DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount];Set<String> autowiredBeans = new LinkedHashSet<>(argumentCount);Assert.state(beanFactory != null, "No BeanFactory available");TypeConverter typeConverter = beanFactory.getTypeConverter();// 遍历每个方法参数,找到匹配的bean对象for (int i = 0; i < arguments.length; i++) {MethodParameter methodParam = new MethodParameter(method, i);DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);currDesc.setContainingClass(bean.getClass());descriptors[i] = currDesc;try {Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);if (arg == null && !this.required) {arguments = null;break;}arguments[i] = arg;} catch (BeansException ex) {throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);}}synchronized (this) {if (!this.cached) {if (arguments != null) {DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length);registerDependentBeans(beanName, autowiredBeans);if (autowiredBeans.size() == argumentCount) {Iterator<String> it = autowiredBeans.iterator();Class<?>[] paramTypes = method.getParameterTypes();for (int i = 0; i < paramTypes.length; i++) {String autowiredBeanName = it.next();if (beanFactory.containsBean(autowiredBeanName) &&beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {cachedMethodArguments[i] = new ShortcutDependencyDescriptor(descriptors[i], autowiredBeanName, paramTypes[i]);}}}this.cachedMethodArguments = cachedMethodArguments;} else {this.cachedMethodArguments = null;}this.cached = true;}}return arguments;
}

这里我们可以看到:

  1. 遍历方法所有的参数;
  2. 经过一系列判断之后,调用AutowireCapableBeanFactory的resolveDependency方法,因为DefaultListableBeanFactory实现啦AutowireCapableBeanFactory接口,最终会走到DefaultListableBeanFactory的resolveDependency()方法;
  3. 找到要注入的Bean对象之后会调用registerDependentBeans()方法,记录依赖关系;

返回AutowiredMethodElement.inject()方法;

findAutowiringMetadata()方法

findAutowiringMetadata()方法详解

/*** 寻找注入点*/
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {// Fall back to class name as cache key, for backwards compatibility with custom callers.String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());// Quick check on the concurrent map first, with minimal locking.InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);if (InjectionMetadata.needsRefresh(metadata, clazz)) {synchronized (this.injectionMetadataCache) {metadata = this.injectionMetadataCache.get(cacheKey);if (InjectionMetadata.needsRefresh(metadata, clazz)) {if (metadata != null) {metadata.clear(pvs);}// 解析注入点并缓存metadata = buildAutowiringMetadata(clazz);this.injectionMetadataCache.put(cacheKey, metadata);}}}return metadata;
}

通过上述代码我们可以看到,首先会拿到BeanName,通过一系列逻辑判断,调用buildAutowiringMetadata()方法解析注入点,拿到注入点信息后放入缓存中,key是BeanName,Value是注入点信息;
回到查找注入点的方法;
回到给注入点赋值的方法

buildAutowiringMetadata()方法

buildAutowiringMetadata()方法详解


private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {// 如果一个Bean的类型是String...,那么则根本不需要进行依赖注入if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {return InjectionMetadata.EMPTY;}List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();Class<?> targetClass = clazz;do {final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();// 遍历targetClass中的所有FieldReflectionUtils.doWithLocalFields(targetClass, field -> {// field上是否存在@Autowired、@Value、@Inject中的其中一个MergedAnnotation<?> ann = findAutowiredAnnotation(field);if (ann != null) {// static filed不是注入点,不会进行自动注入if (Modifier.isStatic(field.getModifiers())) {if (logger.isInfoEnabled()) {logger.info("Autowired annotation is not supported on static fields: " + field);}return;}// 获取 required 属性的值boolean required = determineRequiredStatus(ann);// 构造注入点currElements.add(new AutowiredFieldElement(field, required));}});// 遍历targetClass中的所有MethodReflectionUtils.doWithLocalMethods(targetClass, method -> {Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {return;}// method上是否存在@Autowired、@Value、@Inject中的其中一个MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {// static method不是注入点,不会进行自动注入if (Modifier.isStatic(method.getModifiers())) {if (logger.isInfoEnabled()) {logger.info("Autowired annotation is not supported on static methods: " + method);}return;}// set方法最好有入参if (method.getParameterCount() == 0) {if (logger.isInfoEnabled()) {logger.info("Autowired annotation should only be used on methods with parameters: " +method);}}boolean required = determineRequiredStatus(ann);PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);currElements.add(new AutowiredMethodElement(method, required, pd));}});elements.addAll(0, currElements);targetClass = targetClass.getSuperclass();}while (targetClass != null && targetClass != Object.class);return InjectionMetadata.forElements(elements, clazz);
}

通过上述代码,我们可以看到:
  首先是一个判断,这个判断的作用的是,如果Bean类型是java.*.*或者是Ordered,会直接跳过,不会查找注入点;(java.lang.Integer、java.lang.String、……,JDK的对象不会进行依赖注入)
  再往下我们看到的是一个do while 循环,循环体中有两大块逻辑,一块是遍历所有Field,一块是遍历所有Method:

  • 遍历所有Field
    • 调用findAutowiredAnnotation()方法,找到满足注入点的要求的field;
    • 再判断不是被static修饰的;
    • 调用determineRequiredStatus()方法获取required属性的值
    • 创建AutowiredFieldElement对象放入currElements(注入点缓存)中
  • 遍历所有Method
    • 通过BridgeMethodResolver.findBridgedMethod()判断当前Method是否是桥接方法,如果是找到原方法;
    • 调用findAutowiredAnnotation()方法,找到满足注入点的要求的Method;
    • 再判断不是被static修饰的;
    • 调用determineRequiredStatus()方法获取required属性的值;
    • 创建AutowiredMethodElement对象放入currElements(注入点缓存)中

回到findAutowiringMetadata()方法;

findAutowiredAnnotation()方法

findAutowiredAnnotation()方法详解

@Nullable
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {MergedAnnotations annotations = MergedAnnotations.from(ao);for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {MergedAnnotation<?> annotation = annotations.get(type);if (annotation.isPresent()) {return annotation;}}return null;
}

  通过上述代码可以看到,循序autowiredAnnotationTypes集合中的注解,判断属性或者方法上是否有集合中的注解,autowiredAnnotationTypes集合中注解来源查看AutowiredAnnotationBeanPostProcessor()构造方法;
  回到buildAutowiringMetadata()方法;

AutowiredAnnotationBeanPostProcessor构造器

AutowiredAnnotationBeanPostProcessor()构造方法详解


/*** Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's* standard {@link Autowired @Autowired} and {@link Value @Value} annotations.* <p>Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation,* if available.*/
@SuppressWarnings("unchecked")
public AutowiredAnnotationBeanPostProcessor() {this.autowiredAnnotationTypes.add(Autowired.class);this.autowiredAnnotationTypes.add(Value.class);try {this.autowiredAnnotationTypes.add((Class<? extends Annotation>)ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");} catch (ClassNotFoundException ex) {// JSR-330 API not available - simply skip.}
}

  通过上述代码我们可以看到,AutowiredAnnotationBeanPostProcessor在创建的时候,构造器中会把@Autowired、@Value、@Inject注解放入autowiredAnnotationTypes中(Set<Class<? extends Annotation>> 集合);
  回到findAutowiredAnnotation()方法;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/29124.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 面试题:Java 的文件拷贝方式有几种?哪一种最高效?

在Java编程中&#xff0c;文件操作是常见且重要的任务之一&#xff0c;其中文件拷贝&#xff08;File Copy&#xff09;是一种基本操作。Java提供了多种方式来实现文件拷贝&#xff0c;每种方式在性能、易用性和灵活性上各有优劣。了解并选择最适合的文件拷贝方法&#xff0c;对…

SQL Server数据库安装

原文&#xff1a;https://blog.c12th.cn/archives/26.html SQL Server数据库安装 测试&#xff1a;笔记本原装操作系统&#xff1a;Windows 10 家庭中文版 资源分享链接&#xff1a;提取码&#xff1a;qbt2 注意事项&#xff1a; 请严格按照步骤安装&#xff0c;SQL软件安装较…

el-table

el-table实现滚动效果 表格数据是websocket通信获取的数据&#xff0c;首次获取20条数据&#xff0c;以后新增订阅获取一条&#xff0c;新增一条则向上滑动显示最新数据。 const scroll (tableBody: any) > {// 先清除后设置cancelAnimationFrame(scrollTimer.value);let…

Matlab初识:什么是Matlab?它的历史、发展和应用领域

目录 一、什么是Matlab&#xff1f; 二、Matlab的历史与发展 三、Matlab的应用领域 四、安装和启动Matlab 五、界面介绍 六、第一个Matlab程序 七、总结 一、什么是Matlab&#xff1f; Matlab 是由 MathWorks 公司开发的一款用于数值计算、可视化以及编程的高级技术计算…

mysql 查询某表数据,更新另外一个表字段

1.根据子查询更新表字段(简单推荐) UPDATE demo d set d.user_name (select user_name from user u where u.user_code d.user_code) where d.user_name IS NULL2.使用join关联查询再插入 不想写了&#xff0c;累了有空再补 3.首先查询user表&#xff0c;找出与demo表中相…

spi service实现类加载代码

private static List<Factory> discoverFactories(ClassLoader classLoader) {//spi机制加载类final Iterator<Factory> serviceLoaderIterator ServiceLoader.load(Factory.class, classLoader).iterator();final List<Factory> loadResults new ArrayList…

第二证券今日投资参考:苹果WWDC大会开幕 地产板块再迎催化

上星期五&#xff0c;沪指盘中窄幅震动&#xff0c;创业板指在宁德年代的拖累下大幅下探。到收盘&#xff0c;沪指微涨0.08%报3051.28点&#xff0c;深证成指跌0.9%报9255.68点&#xff0c;创业板指跌2.16%报1781.07点&#xff0c;北证50指数涨0.93%&#xff0c;万得微盘股指数…

【Effective Web】常见的css布局方式--三栏布局

常见的css居中方式–三栏布局 第一种实现&#xff1a;table布局&#xff08;不推荐&#xff09; 缺点&#xff1a;在table加载前&#xff0c;整个table都是空白的&#xff0c;且修改布局排版都十分困难 <table class"container"><td class"left"…

vue:对三种获取更新后的dom的方式进行分析

一、问题分析 由于vue的异步更新机制&#xff0c;我们在同步代码中是无法获取到更新后的dom的信息的 针对这个问题&#xff0c;我们有三种解决方案获取更新后的dom: 1.nextTick() 2.setTimeout() 3.在微任务中获取 因为更新是在同步任务结束后&#xff0c;执行微任务之前…

Python模拟车站检票系统

1 问题 在日常生活中&#xff0c;车站人工检票效率很慢&#xff0c;有没有代替人工检票的系统呢&#xff1f; 2 方法 1.通过接口获取车站名 2.再根据车站名获取到车站的代码 3.然后根据车站代码获取当天的全部车次信息 4.根据当前时间筛选出大于当前时间的车次list 5.通过多线程…

【Linux环境部署】Linux系统Docker安装与配置(一)

文章目录 Docker安装较新版本ubuntu安装docker旧版本&#xff08;<16&#xff09;安装docker完全卸载离线安装 Nvidia Docker安装Nvidia Docker镜像配置 Docker Compose安装&升级 Docker安装 Docker使用手册&#xff1a;Docker中文使用手册 Docker网卡地址修改&#xf…

【数据库编程-SQLite3(三)】Ubuntu下sqlite3的使用

学习分享 1、安装sqlite3命令2、sqlite3点命令3、在Linux命令行下&#xff0c;启动sqlite33.1、编写sql脚本3.2、脚本编写--DDL3.3、进入xxx.db数据库&#xff0c;读取脚本。3.4、再次查看数据库中的表。证明表创建成功。3.5、查看数据表中用户内容3.6、查看表结构3.7、在数据库…

k8s业务上线流程

k8s业务上线流程 搭建好k8s集群之后&#xff0c;需要在集群内部运行一些业务程序&#xff0c;并可以访问&#xff0c;这样的集群才有意义。之前只是自己学习如何搭建集群&#xff0c;如何创建资源对象&#xff0c;更多的是在学习和练习层面&#xff0c;并没有实际用处&#xf…

SpringBoot3使用Swagger

SpringBoot3使用Swagger 项目中的后端接口进行简单的前端展示一、依赖引入二、快速启动1.在application.yml中配置2.或者properties文件,则配置3.启动项目访问swagger 项目中的后端接口进行简单的前端展示 Swagger是一个用于设计、构建、文档化和使用RESTful Web服务的开源工具…

TWM论文阅读笔记

这是ICLR2023的一篇world model论文&#xff0c;用transformer来做世界模型的sequence prediction。文章贡献是transformer-based world model&#xff08;不同于以往的如transdreamer的world model&#xff0c;本文的transformer-based world model在inference 的时候可以丢掉…

Xcode编译报错 #error unsupported Swift architecture

1. 问题描述&#xff1a; Xcode15 引入某些三方库时&#xff0c;真机跑起来没问题&#xff1b;但模拟器build时报错卡在 #error unsupported Swift architecture&#xff0c;注释掉代码也不行&#xff1b; 2. 解决办法&#xff1a; 得找到Rosetta类型模拟器才能run起来&…

信号处理中的梯型权重操作(Tapering)

目录 1. 引言2. 一个Tapering操作的例子3. Tapering操作的简单实现延伸阅读1. 引言 Tapering 操作是对信号数据在水平和垂直方向上应用梯形权重,这个操作可以减弱数据边界效应,从而在进行傅里叶变换时减少伪影和边缘效应。本文将通过一个简单的例子来展示 Tapering 操作的具…

ARM应用处理器系列

ARM 应用处理器系列是指基于 ARM 架构设计的用于各种应用场景的处理器。这些处理器被广泛应用于移动设备、嵌入式系统、服务器、物联网设备等领域。以下是一些主要的 ARM 应用处理器系列&#xff1a; 1. Cortex-A 系列 Cortex-A 系列处理器专为高性能和低功耗应用设计&#xf…

【C/C++】工业级别的日志文件轮转策略原理

日志文件轮转&#xff08;Log Rotation&#xff09;是一种日志管理策略&#xff0c;用于自动管理日志文件的大小和数量。随着应用程序运行时间的增加&#xff0c;日志文件可能会变得非常大&#xff0c;这不仅会占用大量的磁盘空间&#xff0c;还可能影响应用程序的性能。日志文…

函数模板的具体化

函数模板优点是通用性&#xff0c;可以解决某个方面的普遍性问题&#xff0c;但是这个世界上的事情不是绝对的&#xff0c;有普遍的&#xff0c;就有绝对的。举个栗子&#xff1a; #include <iostream> using namespace std; template <typename T> void Swap(T &…