Spring源码深度解析(郝佳)-学习-源码解析-基于注解注入(二)

在Spring源码深度解析(郝佳)-学习-源码解析-基于注解bean解析(一)博客中,己经对有注解的类进行了解析,得到了BeanDefinition,但是我们看到属性并没有封装到BeanDefinition(关于BeanDefinition的定义,这里不做过多的解释了,就是定义了Bean的属性,比如单例,多例,依赖,工厂方法,是否使用代理,等,而Bean的创建,是基于Bean的定义来的)中,而Bean创建的时候,是如何注入的呢?今天,我们带着这个问题,继续来跟踪基于注解的属性是如何注入。
先上示例。

Car.java

@Component
@Data
public class Car {
    private String color = "red";
}

Dog.java

@Component
public class Dog {

}

MyRequestAnnotation.java

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Service
public @interface  MyRequestAnnotation {

    String value() default "";
}

MyTestAnnotation.java

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
@Mapping
@MyRequestAnnotation
public @interface MyTestAnnotation {
    String name() default "";
    
    @AliasFor("path")
    String[] value() default {};
    
    RequestMethod[] method() default {};
}

User.java

@Service("xxxx")
@MyTestAnnotation("/user/info")
public class User {
    @Autowired
    private Car car;

    @Autowired
    private Dog dog;
    
    public void drive(){
        System.out.println(car);
    }
}

spring35_resource_inject_1.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p" xmlns:oxm="http://www.springframework.org/schema/oxm"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
       
    <context:component-scan base-package="com.spring_1_100.test_31_40.test35_resource_inject.anno"/>

</beans>

测试:

public static void main(String[] args) {
    ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring_1_100/config_31_40/spring35_resource_inject_1.xml");
    User user = (User) ac.getBean("xxxx");
    user.drive();
}

结果输出:
Spring源码深度解析(郝佳)-学习-源码解析-基于注解注入(二)

而本篇博客的主要目的就是研究User对象中的car是如何注入的。
我们知道属性注入都是在Spring源码中的populateBean这个方法,那我们来测试一下,在这个方法之前和在这个方法之后打断点,看属性car有没有被注入进去。
Spring源码深度解析(郝佳)-学习-源码解析-基于注解注入(二)
在方法调用前,car和,dog都是空
Spring源码深度解析(郝佳)-学习-源码解析-基于注解注入(二)

方法调用后,car 和dog 都被实例化了。那我们就来重点分析 populateBean方法,其实Spring无论是xml配置的属性,还是通过注解依赖注入的属性,都是通过这个方法(populateBean)来进行属性填充的。
Spring源码深度解析(郝佳)-学习-源码解析-基于注解注入(二)

经过我不断的打断点,寻寻觅觅,竟然是通过AutowiredAnnotationBeanPostProcessor的postPropertyValues方法进行属性注入的。而AutowiredAnnotationBeanPostProcessor又是如何保存到AbstractBeanFactory的beanPostProcessors里的呢(因为在populateBean方法中调用了getBeanPostProcessors()方法,才得到所有的BeanPostProcessor,而getBeanPostProcessors()方法获取BeanPostProcessor是直接从AbstractBeanFactory的beanPostProcessors集合中取出来的)?带着好奇,我们来探索一番。因此,通过全局查找发现AutowiredAnnotationBeanPostProcessor.class关键字只在AnnotationConfigUtils的registerAnnotationConfigProcessors方法和AutowiredAnnotationBeanPostProcessor的构造函数中出现过,如下图所示,因此分别在这两处打上断点。
Spring源码深度解析(郝佳)-学习-源码解析-基于注解注入(二)

最终,我们发现AutowiredAnnotationBeanPostProcessor的BeanDefinition定义是在ComponentScanBeanDefinitionParser类的registerComponents方法处调用的。如下图,而ComponentScanBeanDefinitionParser这个类主要是Bean的注解解析时调用。
Spring源码深度解析(郝佳)-学习-源码解析-基于注解注入(二)
而AutowiredAnnotationBeanPostProcessor是在哪里调用创建的呢?继续跟踪断点。终于到了AutowiredAnnotationBeanPostProcessor的构造函数中。
Spring源码深度解析(郝佳)-学习-源码解析-基于注解注入(二)

从下图中可以看出,AutowiredAnnotationBeanPostProcessor的实例化是在refresh()方法的注册bean的处理器方法中调用。
Spring源码深度解析(郝佳)-学习-源码解析-基于注解注入(二)

Spring源码深度解析(郝佳)-学习-源码解析-基于注解注入(二)
Spring源码深度解析(郝佳)-学习-源码解析-基于注解注入(二)

PostProcessorRegistrationDelegate.java

private static void registerBeanPostProcessors(
		ConfigurableListableBeanFactory beanFactory, List postProcessors) {

	for (BeanPostProcessor postProcessor : postProcessors) {
		beanFactory.addBeanPostProcessor(postProcessor);
	}
}

AbstractBeanFactory.java

public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
	Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
	this.beanPostProcessors.remove(beanPostProcessor);
	this.beanPostProcessors.add(beanPostProcessor);
	if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
		this.hasInstantiationAwareBeanPostProcessors = true;
	}
	if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
		this.hasDestructionAwareBeanPostProcessors = true;
	}
}

通过代码,最终,我们看到AutowiredAnnotationBeanPostProcessor被加入到beanPostProcessors中。到这里,我们知道了,在populateBean方法中,调用getBeanPostProcessors()方法时,能获取到AutowiredAnnotationBeanPostProcessor对象了。通过上面的铺垫,下面,我们来正式分析Spring是如何通过注解来进行属性注入的。

AutowiredAnnotationBeanPostProcessor.java

public PropertyValues postProcessPropertyValues(
		PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

	InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
	try {
		metadata.inject(bean, beanName, pvs);
	}
	catch (Throwable ex) {
		throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
	}
	return pvs;
}

private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
	//从缓存中获取
	String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
	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);
				}
				try {
					//缓存中不存在,直接构建metadata
					metadata = buildAutowiringMetadata(clazz);
					this.injectionMetadataCache.put(cacheKey, metadata);
				}
				catch (NoClassDefFoundError err) {
					throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() +
							"] for autowiring metadata: could not find class that it depends on", err);
				}
			}
		}
	}
	return metadata;
}

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
  LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
  Class<?> targetClass = clazz;

  do {
    final LinkedList<InjectionMetadata.InjectedElement> currElements =
        new LinkedList<InjectionMetadata.InjectedElement>();

    ReflectionUtils.doWithLocalFields(targetClass, new ReflectionUtils.FieldCallback() {
      @Override
      public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
      	//找到当前属性的所有注解信息
        AnnotationAttributes ann = findAutowiredAnnotation(field);
        if (ann != null) {
          if (Modifier.isStatic(field.getModifiers())) {
            if (logger.isWarnEnabled()) {
              logger.warn("Autowired annotation is not supported on static fields: " + field);
            }
            return;
          }
          boolean required = determineRequiredStatus(ann);
          currElements.add(new AutowiredFieldElement(field, required));
        }
      }
    });

    ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {
      @Override
      public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
        Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
        if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
          return;
        }
        AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
        if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
          if (Modifier.isStatic(method.getModifiers())) {
            if (logger.isWarnEnabled()) {
              logger.warn("Autowired annotation is not supported on static methods: " + method);
            }
            return;
          }
          if (method.getParameterTypes().length == 0) {
            if (logger.isWarnEnabled()) {
              logger.warn("Autowired annotation should 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 new InjectionMetadata(clazz, elements);
}
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
  for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
    AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
    if (attributes != null) {
      return attributes;
    }
  }
  return null;
}

ReflectionUtils.java

public static void doWithLocalFields(Class<?> clazz, FieldCallback fc) {
  //获取类的所有的属性
  for (Field field : getDeclaredFields(clazz)) {
    try {
      fc.doWith(field);
    }
    catch (IllegalAccessException ex) {
      throw new IllegalStateException("Not allowed to access field '" + field.getName() + "': " + ex);
    }
  }
}

AutowiredAnnotationBeanPostProcessor.java

private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
  //autowiredAnnotationTypes中是@Autowired和@Value注解,在AutowiredAnnotationBeanPostProcessor实例化时加入其中的
  for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
    AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
    if (attributes != null) {
      return attributes;
    }
  }
  return null;
}

Spring源码深度解析(郝佳)-学习-源码解析-基于注解注入(二)

AnnotatedElementUtils.java

public static AnnotationAttributes getMergedAnnotationAttributes(AnnotatedElement element, Class<? extends Annotation> annotationType) {
	Assert.notNull(annotationType, "annotationType must not be null");
	return getMergedAnnotationAttributes(element, annotationType.getName());
}

public static AnnotationAttributes getMergedAnnotationAttributes(AnnotatedElement element, String annotationName) {
	return getMergedAnnotationAttributes(element, annotationName, false, false);
}

public static AnnotationAttributes getMergedAnnotationAttributes(AnnotatedElement element, String annotationName,
		boolean classValuesAsString, boolean nestedAnnotationsAsMap) {

	AnnotationAttributes attributes = searchWithGetSemantics(element, annotationName,
		new MergedAnnotationAttributesProcessor(annotationName, classValuesAsString, nestedAnnotationsAsMap));
	AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString,
		nestedAnnotationsAsMap);
	return attributes;
}


private static  T searchWithGetSemantics(AnnotatedElement element, String annotationName, Processor processor) {
	try {
		return searchWithGetSemantics(element, annotationName, processor, new HashSet(), 0);
	}
	catch (Throwable ex) {
		AnnotationUtils.rethrowAnnotationConfigurationException(ex);
		throw new IllegalStateException("Failed to introspect annotations on " + element, ex);
	}
}

private static <T> T searchWithGetSemantics(AnnotatedElement element, String annotationName,
    Processor<T> processor, Set<AnnotatedElement> visited, int metaDepth) {

  Assert.notNull(element, "AnnotatedElement must not be null");
  Assert.hasText(annotationName, "annotationName must not be null or empty");
  //注解去重
  if (visited.add(element)) {
    try {

      //获取属性上的所有注解
      List<Annotation> declaredAnnotations = Arrays.asList(element.getDeclaredAnnotations());
      T result = searchWithGetSemanticsInAnnotations(element, declaredAnnotations, annotationName, processor,
        visited, metaDepth);
      if (result != null) {
        return result;
      }

      List<Annotation> inheritedAnnotations = new ArrayList<Annotation>();
      for (Annotation annotation : element.getAnnotations()) {
        if (!declaredAnnotations.contains(annotation)) {
          inheritedAnnotations.add(annotation);
        }
      }

      // Continue searching within inherited annotations
      result = searchWithGetSemanticsInAnnotations(element, inheritedAnnotations, annotationName, processor,
        visited, metaDepth);
      if (result != null) {
        return result;
      }
    }
    catch (Exception ex) {
      AnnotationUtils.handleIntrospectionFailure(element, ex);
    }
  }

  return null;
}


private static <T> T searchWithGetSemanticsInAnnotations(AnnotatedElement annotatedElement, List<Annotation> annotations,
		String annotationName, Processor<T> processor, Set<AnnotatedElement> visited, int metaDepth) {

	//递归遍历所有的注解
	for (Annotation annotation : annotations) {
		//非java.lang.annotation包开头的注解,并且注解的名称为Autowired或者Value
		if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)
				&& (annotation.annotationType().getName().equals(annotationName) || metaDepth > 0)) {
			T result = processor.process(annotatedElement, annotation, metaDepth);
			if (result != null) {
				return result;
			}
		}
	}

	//主要是递归查找,比如Car car 属性配置了@MyAutowired注解,但是@MyAutowired又配置了@Autowired注解
	for (Annotation annotation : annotations) {
		if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) {
			T result = searchWithGetSemantics(annotation.annotationType(), annotationName, processor, visited,
				metaDepth + 1);
			if (result != null) {
				processor.postProcess(annotatedElement, annotation, result);
				return result;
			}
		}
	}

	return null;
}

MergedAnnotationAttributesProcessor.java

public AnnotationAttributes process(AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) {
	boolean found = annotation.annotationType().getName().equals(this.annotationName);
	return (found ? AnnotationUtils.getAnnotationAttributes(annotatedElement, annotation,
		this.classValuesAsString, this.nestedAnnotationsAsMap, true) : null);
}

AnnotationUtils.java

static AnnotationAttributes getAnnotationAttributes(AnnotatedElement annotatedElement, Annotation annotation,
		boolean classValuesAsString, boolean nestedAnnotationsAsMap, boolean mergeMode) {

	if (!mergeMode) {
		annotation = synthesizeAnnotation(annotation, annotatedElement);
	}
	
	Class<? extends Annotation> annotationType = annotation.annotationType();
	AnnotationAttributes attrs = new AnnotationAttributes(annotationType);
	//获取注解的所有方法并遍历
	for (Method method : getAttributeMethods(annotationType)) {
		try {
			//通过反射,获取注解配置的值
			Object value = method.invoke(annotation);
			//获取注解配置的默认值
			Object defaultValue = method.getDefaultValue();
			if (mergeMode && (defaultValue != null)) {
				if (ObjectUtils.nullSafeEquals(value, defaultValue)) {
					//将值设置为Spring的默认值 
					value = DEFAULT_VALUE_PLACEHOLDER;
				}
			}
			attrs.put(method.getName(),
				adaptValue(annotatedElement, value, classValuesAsString, nestedAnnotationsAsMap));
		}
		catch (Exception ex) {
			if (ex instanceof InvocationTargetException) {
				Throwable targetException = ((InvocationTargetException) ex).getTargetException();
				rethrowAnnotationConfigurationException(targetException);
			}
			throw new IllegalStateException("Could not obtain annotation attribute value for " + method, ex);
		}
	}
	return attrs;
}

当这个方法执行完毕后,我们得到Spring result是AnnotationAttributes。

Spring源码深度解析(郝佳)-学习-源码解析-基于注解注入(二)
我们再回到AnnotatedElementUtils的getMergedAnnotationAttributes方法中。

AnnotationUtils.java

static void postProcessAnnotationAttributes(AnnotatedElement element, AnnotationAttributes attributes,
		boolean classValuesAsString, boolean nestedAnnotationsAsMap) {

	//属性是不是为空
	if (attributes == null) {
		return;
	}

	Class<? extends Annotation> annotationType = attributes.annotationType();

	//值是不是被替换
	Set<String> valuesAlreadyReplaced = new HashSet<String>();
	//注解的属性方法是否有别名
	Map<String, List<String>> aliasMap = getAttributeAliasMap(annotationType);
	//如果有别名,将做别名相关的处理
	for (String attributeName : aliasMap.keySet()) {
		if (valuesAlreadyReplaced.contains(attributeName)) {
			continue;
		}
		Object value = attributes.get(attributeName);
		boolean valuePresent = (value != null && value != DEFAULT_VALUE_PLACEHOLDER);

		for (String aliasedAttributeName : aliasMap.get(attributeName)) {
			if (valuesAlreadyReplaced.contains(aliasedAttributeName)) {
				continue;
			}

			Object aliasedValue = attributes.get(aliasedAttributeName);
			boolean aliasPresent = (aliasedValue != null && aliasedValue != DEFAULT_VALUE_PLACEHOLDER);

			// Something to validate or replace with an alias?
			if (valuePresent || aliasPresent) {
				if (valuePresent && aliasPresent) {
					// Since annotation attributes can be arrays, we must use ObjectUtils.nullSafeEquals().
					if (!ObjectUtils.nullSafeEquals(value, aliasedValue)) {
						String elementAsString = (element != null ? element.toString() : "unknown element");
						String msg = String.format("In AnnotationAttributes for annotation [%s] declared on [%s], " +
								"attribute [%s] and its alias [%s] are declared with values of [%s] and [%s], " +
								"but only one declaration is permitted.", annotationType.getName(),
								elementAsString, attributeName, aliasedAttributeName,
								ObjectUtils.nullSafeToString(value), ObjectUtils.nullSafeToString(aliasedValue));
						throw new AnnotationConfigurationException(msg);
					}
				}
				else if (aliasPresent) {
					// Replace value with aliasedValue
					attributes.put(attributeName,
							adaptValue(element, aliasedValue, classValuesAsString, nestedAnnotationsAsMap));
					valuesAlreadyReplaced.add(attributeName);
				}
				else {
					// Replace aliasedValue with value
					attributes.put(aliasedAttributeName,
							adaptValue(element, value, classValuesAsString, nestedAnnotationsAsMap));
					valuesAlreadyReplaced.add(aliasedAttributeName);
				}
			}
		}
	}

	//将注解属性方法的值是<SPRING DEFAULT VALUE PLACEHOLDER>替换成属性方法的默认值,如@Autowired的required的默认值是true
	for (String attributeName : attributes.keySet()) {
		if (valuesAlreadyReplaced.contains(attributeName)) {
			continue;
		}
		Object value = attributes.get(attributeName);
		if (value == DEFAULT_VALUE_PLACEHOLDER) {
			attributes.put(attributeName,
				adaptValue(element, getDefaultValue(annotationType, attributeName), classValuesAsString,
					nestedAnnotationsAsMap));
		}
	}
}

Spring源码深度解析(郝佳)-学习-源码解析-基于注解注入(二)

经过漫长枯燥的解析,我们终于得到了Car 的@Autowired注解的required属性的默认值是true 。经过上面的分析,我们得到了InjectionMetadata对象,下面,我们来继续分析属性的注入。

InjectionMetadata.java

public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
	Collection<InjectedElement> elementsToIterate =
			(this.checkedElements != null ? this.checkedElements : this.injectedElements);
	if (!elementsToIterate.isEmpty()) {
		boolean debug = logger.isDebugEnabled();
		for (InjectedElement element : elementsToIterate) {
			if (debug) {
				logger.debug("Processing injected element of bean '" + beanName + "': " + element);
			}
			element.inject(target, beanName, pvs);
		}
	}
}

AutowiredFieldElement.java

protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
	Field field = (Field) this.member;
	try {
		Object value;
		if (this.cached) {
			value = resolvedCachedArgument(beanName, this.cachedFieldValue);
		}
		else {
			//创建属性的描述器
			DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
			//设置属性的bean 的class 
			desc.setContainingClass(bean.getClass());
			Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);
			//获取工厂bean的类型转换器 
			TypeConverter typeConverter = beanFactory.getTypeConverter();
			//获取到属性的具体值,比如Car对象 
			value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
			synchronized (this) {
				if (!this.cached) {
					if (value != null || this.required) {
						this.cachedFieldValue = desc;
						//注册bean之间的依赖关系,也就是User中有属性Car, Car 在User中使用过等,这样的信息
						registerDependentBeans(beanName, autowiredBeanNames);
						if (autowiredBeanNames.size() == 1) {
							String autowiredBeanName = autowiredBeanNames.iterator().next();
							if (beanFactory.containsBean(autowiredBeanName)) {
								// 名称是否匹配
								if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
									// 创建bean的引用
									this.cachedFieldValue = new RuntimeBeanReference(autowiredBeanName);
								}
							}
						}
					}
					else {
						this.cachedFieldValue = null;
					}
					this.cached = true;
				}
			}
		}
		if (value != null) {
			// 通过反射将属性值设置到bean中 
			ReflectionUtils.makeAccessible(field);
			field.set(bean, value);
		}
	}
	catch (Throwable ex) {
		throw new BeanCreationException("Could not autowire field: " + field, ex);
	}
}

DefaultListableBeanFactory.java

public Object resolveDependency(DependencyDescriptor descriptor, String beanName,
		Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {

	descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
	if (descriptor.getDependencyType().equals(javaUtilOptionalClass)) {
		return new OptionalDependencyFactory().createOptionalDependency(descriptor, beanName);
	}
	else if (ObjectFactory.class == descriptor.getDependencyType()) {
		return new DependencyObjectFactory(descriptor, beanName);
	}
	else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
		return new DependencyProviderFactory().createDependencyProvider(descriptor, beanName);
	}
	else {
		//如果属性是延迟初始化,做相应的处理
		Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, beanName);
		if (result == null) {
			//真正的解析bean
			result = doResolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter);
		}
		return result;
	}
}

public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
		Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {

	Class<?> type = descriptor.getDependencyType();
	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);
			value = evaluateBeanDefinitionString(strVal, bd);
		}
		TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
		return (descriptor.getField() != null ?
				converter.convertIfNecessary(value, type, descriptor.getField()) :
				converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
	}

	if (type.isArray()) {
		Class<?> componentType = type.getComponentType();
		DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
		targetDesc.increaseNestingLevel();
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, targetDesc);
		if (matchingBeans.isEmpty()) {
			if (descriptor.isRequired()) {
				raiseNoSuchBeanDefinitionException(componentType, "array of " + componentType.getName(), descriptor);
			}
			return null;
		}
		if (autowiredBeanNames != null) {
			autowiredBeanNames.addAll(matchingBeans.keySet());
		}
		TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
		Object result = converter.convertIfNecessary(matchingBeans.values(), type);
		if (getDependencyComparator() != null && result instanceof Object[]) {
			Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans));
		}
		return result;
	}
	else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
		Class<?> elementType = descriptor.getCollectionType();
		if (elementType == null) {
			if (descriptor.isRequired()) {
				throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]");
			}
			return null;
		}
		DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
		targetDesc.increaseNestingLevel();
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, targetDesc);
		if (matchingBeans.isEmpty()) {
			if (descriptor.isRequired()) {
				raiseNoSuchBeanDefinitionException(elementType, "collection of " + elementType.getName(), descriptor);
			}
			return null;
		}
		if (autowiredBeanNames != null) {
			autowiredBeanNames.addAll(matchingBeans.keySet());
		}
		TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
		Object result = converter.convertIfNecessary(matchingBeans.values(), type);
		if (getDependencyComparator() != null && result instanceof List) {
			Collections.sort((List<?>) result, adaptDependencyComparator(matchingBeans));
		}
		return result;
	}
	else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
		Class<?> keyType = descriptor.getMapKeyType();
		if (String.class != keyType) {
			if (descriptor.isRequired()) {
				throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() +
						"] must be [java.lang.String]");
			}
			return null;
		}
		Class<?> valueType = descriptor.getMapValueType();
		if (valueType == null) {
			if (descriptor.isRequired()) {
				throw new FatalBeanException("No value type declared for map [" + type.getName() + "]");
			}
			return null;
		}
		DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
		targetDesc.increaseNestingLevel();
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, targetDesc);
		if (matchingBeans.isEmpty()) {
			if (descriptor.isRequired()) {
				raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor);
			}
			return null;
		}
		if (autowiredBeanNames != null) {
			autowiredBeanNames.addAll(matchingBeans.keySet());
		}
		return matchingBeans;
	}
	else {
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
		if (matchingBeans.isEmpty()) {
			//如果autowired的required为true,但是容器中并没有这个bean,则抛出异常
			if (descriptor.isRequired()) {
				raiseNoSuchBeanDefinitionException(type, "", descriptor);
			}
			return null;
		}
		//如果通过名称获取到多个bean对象
		if (matchingBeans.size() > 1) {
			String primaryBeanName = determineAutowireCandidate(matchingBeans, descriptor);
			//如果没有设置@Primary注解,则直接抛出异常
			if (primaryBeanName == null) {
				throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());
			}
			if (autowiredBeanNames != null) {
				//如果设置了@Primary,则取设置了@Primary的作为注入值
				autowiredBeanNames.add(primaryBeanName);
			}
			return matchingBeans.get(primaryBeanName);
		}
		Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
		if (autowiredBeanNames != null) {
			autowiredBeanNames.add(entry.getKey());
		}
		//返回属性值
		return entry.getValue();
	}
}


protected Map<String, Object> findAutowireCandidates(
		String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {

	String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
			this, requiredType, true, descriptor.isEager());
	Map<String, Object> result = new LinkedHashMap<String, Object>(candidateNames.length);
	for (Class<?> autowiringType : this.resolvableDependencies.keySet()) {
		if (autowiringType.isAssignableFrom(requiredType)) {
			Object autowiringValue = this.resolvableDependencies.get(autowiringType);
			autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
			if (requiredType.isInstance(autowiringValue)) {
				result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
				break;
			}
		}
	}
	for (String candidateName : candidateNames) {
		//不是自己引用自己,包括类对象是否引用了自己的工厂方法。
		if (!isSelfReference(beanName, candidateName) && isAutowireCandidate(candidateName, descriptor)) {
			//到这里,我们终于看到了关键方法,通过getBean获取car的bean对象
			result.put(candidateName, getBean(candidateName));
		}
	}
	if (result.isEmpty()) {
		DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
		for (String candidateName : candidateNames) {
			if (!candidateName.equals(beanName) && isAutowireCandidate(candidateName, fallbackDescriptor)) {
				result.put(candidateName, getBean(candidateName));
			}
		}
	}
	return result;
}

到这里,我们己经得到了属性的具体值。我们再次回到属性注入方法,inject ,我们到这里,己经将属性的注入分析完了,我们还是来总结一下吧。

  1. 获取到注解的所有的属性。
  2. 查看注解中是否包含@Autowired注解或者@Value注解
  3. 如果有@Autowired注解,获取@Autowired注解的属性方法required的值
  4. 调用getBean()方法,获取属性对象
  5. 通过反射将属性值注入对象

到这里,己经将User 的Car 属性注入解析完成,Dog对象,也是相同的解析办法,这里将不再做过多的缀述了。

本文的 github 地址是
https://github.com/quyixiao/spring_tiny/tree/master/src/main/java/com/spring_1_100/test_31_40/test35_resource_inject