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(); }
結果輸出:
而本篇部落格的主要目的就是研究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 ,我們到這裡,己經將屬性的注入分析完了,我們還是來總結一下吧。
- 獲取到註解的所有的屬性。
- 檢視註解中是否包含@Autowired註解或者@Value註解
- 如果有@Autowired註解,獲取@Autowired註解的屬性方法required的值
- 呼叫getBean()方法,獲取屬性物件
- 通過反射將屬性值注入物件
到這裡,己經將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
相關文章
- Spring原始碼深度解析(郝佳)-學習-原始碼解析-Spring MVCSpring原始碼MVC
- Spring原始碼解析——依賴注入(二)Spring原始碼依賴注入
- Spring @Profile註解使用和原始碼解析Spring原始碼
- 【spring原始碼學習】spring的事務管理的原始碼解析Spring原始碼
- OkHttp原始碼深度解析HTTP原始碼
- SnapHelper原始碼深度解析原始碼
- Vuex 原始碼深度解析Vue原始碼
- VueRouter 原始碼深度解析Vue原始碼
- Spring原始碼解析之基礎應用(二)Spring原始碼
- Spring原始碼解析之BeanFactoryPostProcessor(二)Spring原始碼Bean
- spring原始碼解析:元註解功能的實現Spring原始碼
- Spring原始碼系列:BeanDefinition原始碼解析Spring原始碼Bean
- Spring5原始碼深度解析(一)之理解Configuration註解Spring原始碼
- Laravel 依賴注入原始碼解析Laravel依賴注入原始碼
- 0原始碼基礎學習Spring原始碼系列(一)——Bean注入流程原始碼SpringBean
- spring原始碼深度解析— IOC 之 bean 建立Spring原始碼Bean
- spring原始碼深度解析— IOC 之 自定義標籤解析Spring原始碼
- React Hooks原始碼深度解析ReactHook原始碼
- Spring原始碼學習之:spring註解@TransactionalSpring原始碼
- spring原始碼解析之IOC容器(二)------載入和註冊Spring原始碼
- 【spring原始碼學習】spring的事件釋出監聽機制原始碼解析Spring原始碼事件
- mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入MapperMyBatis原始碼APP
- SDWebImage原始碼解析之SDWebImageManager的註解Web原始碼
- 【Spring原始碼分析】AOP原始碼解析(上篇)Spring原始碼
- 【Spring原始碼分析】AOP原始碼解析(下篇)Spring原始碼
- [原始碼解析]深度學習利器之自動微分(3) --- 示例解讀原始碼深度學習
- Spring 原始碼(7)Spring的註解是如何解析的?Spring原始碼
- spring原始碼深度解析— IOC 之 預設標籤解析(上)Spring原始碼
- spring原始碼深度解析— IOC 之 預設標籤解析(下)Spring原始碼
- Spring AOP 原始碼解析Spring原始碼
- spring原始碼解析之IOC容器(四)——屬性注入Spring原始碼
- spring原始碼解析之IOC容器(三)——依賴注入Spring原始碼依賴注入
- spring原始碼深度解析— IOC 之 屬性填充Spring原始碼
- Java 基礎(二)集合原始碼解析 IteratorJava原始碼
- 我該如何學習spring原始碼以及解析bean定義的註冊Spring原始碼Bean
- 【原始碼SOLO】Retrofit2原始碼解析(二)原始碼
- RecyclerView用法和原始碼深度解析View原始碼
- KubeSphere 後端原始碼深度解析後端原始碼