Spring原始碼深度解析(郝佳)-學習-原始碼解析-基於註解注入(二)

quyixiao發表於2020-10-15

在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();
}

結果輸出:
在這裡插入圖片描述

而本篇部落格的主要目的就是研究User物件中的car是如何注入的。
我們知道屬性注入都是在Spring原始碼中的populateBean這個方法,那我們來測試一下,在這個方法之前和在這個方法之後打斷點,看屬性car有沒有被注入進去。
在這裡插入圖片描述
在方法呼叫前,car和,dog都是空
在這裡插入圖片描述

方法呼叫後,car 和dog 都被例項化了。那我們就來重點分析 populateBean方法,其實Spring無論是xml配置的屬性,還是通過註解依賴注入的屬性,都是通過這個方法(populateBean)來進行屬性填充的。
在這裡插入圖片描述

經過我不斷的打斷點,尋尋覓覓,竟然是通過AutowiredAnnotationBeanPostProcessor的postPropertyValues方法進行屬性注入的。而AutowiredAnnotationBeanPostProcessor又是如何儲存到AbstractBeanFactory的beanPostProcessors裡的呢(因為在populateBean方法中呼叫了getBeanPostProcessors()方法,才得到所有的BeanPostProcessor,而getBeanPostProcessors()方法獲取BeanPostProcessor是直接從AbstractBeanFactory的beanPostProcessors集合中取出來的)?帶著好奇,我們來探索一番。因此,通過全域性查詢發現AutowiredAnnotationBeanPostProcessor.class關鍵字只在AnnotationConfigUtils的registerAnnotationConfigProcessors方法和AutowiredAnnotationBeanPostProcessor的建構函式中出現過,如下圖所示,因此分別在這兩處打上斷點。
在這裡插入圖片描述

最終,我們發現AutowiredAnnotationBeanPostProcessor的BeanDefinition定義是在ComponentScanBeanDefinitionParser類的registerComponents方法處呼叫的。如下圖,而ComponentScanBeanDefinitionParser這個類主要是Bean的註解解析時呼叫。
在這裡插入圖片描述
而AutowiredAnnotationBeanPostProcessor是在哪裡呼叫建立的呢?繼續跟蹤斷點。終於到了AutowiredAnnotationBeanPostProcessor的建構函式中。
在這裡插入圖片描述

從下圖中可以看出,AutowiredAnnotationBeanPostProcessor的例項化是在refresh()方法的註冊bean的處理器方法中呼叫。
在這裡插入圖片描述

在這裡插入圖片描述
在這裡插入圖片描述

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;
}

在這裡插入圖片描述

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。

在這裡插入圖片描述
我們再回到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));
		}
	}
}

在這裡插入圖片描述

經過漫長枯燥的解析,我們終於得到了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

相關文章