spring 源码系列(六)- 处理@AutoWired和@Value的后置处理器AutowiredAnnotationBeanPostProcessor

0 总流程图

在这里插入图片描述

1 介绍

AutowiredAnnotationBeanPostProcessor用于处理@AutoWired和@Value标签,以下面的代码为例:

@Component
@PropertySource("classpath:db.properties")
public class AutoWiredBean {
    @Autowired
    private MessageService messageService;

    @Value("${db.driver}")
    private String driverClass;
    
}

同时,MessageService的实际Bean是其实现类MessageServiceImpl:

@Service
public class MessageServiceImpl implements MessageService {

    public String getMessage() {
        return "hello world";
    }
}

经过AutowiredAnnotationBeanPostProcessor对该类的处理后,MessageServiceImpl和${db.driver}的具体值“com.mysql.jdbc.Driver”就会注入到AutoWiredBean中。

2 原理

2.1 何时被注册

AutowiredAnnotationBeanPostProcessor主要通过下面两种方式进行注册:

  1. 调用AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
  2. refresh()方法中的registerBeanPostProcessors();

对于第一种情况,我的另一篇博客“spring 之 AnnotationConfigApplicationContext”的3.1小节对registerAnnotationConfigProcessors()进行了详细地介绍,感兴趣的可以看看。
第二种情况就不进行详细介绍了。

2.2 何时被调用

先看看类的声明:

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
		implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware 

可以看到,该类继承了InstantiationAwareBeanPostProcessorAdapter,而这个类又是InstantiationAwareBeanPostProcessor的子类,因此会在refresh()方法的populateBean()中被调用:

	protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
		PropertyValues pvs = mbd.getPropertyValues();
	
		//...忽略一部分代码

		if (hasInstAwareBpps || needsDepCheck) {
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			if (hasInstAwareBpps) {
				//获取所有的BeanPostProcessor并遍历
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					//如果该BeanPostProcessor属于InstantiationAwareBeanPostProcessor类的话,则调用postProcessPropertyValues(...)方法
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvs == null) {
							return;
						}
					}
				}
			}
		//...略
	}

对populate()方法感兴趣的小伙伴,建议阅读spring的refresh()方法。

3 postProcessPropertyValues()方法

@Override
	public PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
		//1. 将该bean下的所有@AutoWired和@Value的属性或方法一起被封装成InjectionMetadata类
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {	
		//2. 注入metadata
			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;
	}

3.1 findAutowiringMetadata():获取类的InjectionMetadata

	private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
		//获取缓存的key
		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 {
						//生成bean对应的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;
	}

接着看buildAutowiringMetadata():

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

		do {
			//1. 声明一个currElements,用于存储metadata
			final LinkedList<InjectionMetadata.InjectedElement> currElements =
					new LinkedList<InjectionMetadata.InjectedElement>();
			//2. 利用反射获取该类的所有field,并将field作为参数调用doWith(field)方法
			ReflectionUtils.doWithLocalFields(targetClass, new ReflectionUtils.FieldCallback() {
				@Override
				public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
					//3. 查看属性field是否是@AutoWired或者@Value
					AnnotationAttributes ann = findAutowiredAnnotation(field);
					if (ann != null) {
						//@Autowired或者@Value的属性是不能为static的
						if (Modifier.isStatic(field.getModifiers())) {
							//打印warn日志
							return;
						}
						boolean required = determineRequiredStatus(ann);
						//4. 将该field封装成AutowiredFieldElement,再存入currElements中
						currElements.add(new AutowiredFieldElement(field, required));
					}
				}
			});

			//5. 利用反射获取该类的所有方法method,并将method作为参数调用doWith(method)方法
			ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {
				@Override
				public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
					Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
					//判断,略
					// 6. 同第2点
					AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
					if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
						if (Modifier.isStatic(method.getModifiers())) {
							//打印warn日志
							return;
						}
						if (method.getParameterTypes().length == 0) {
							//打印warn日志
						}
						boolean required = determineRequiredStatus(ann);
						PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
						//7. 将该method封装成AutowiredFieldElement,再存入currElements中
						currElements.add(new AutowiredMethodElement(method, required, pd));
					}
				}
			});

			//8.在解析完Bean的类型之后,递归的解析其父类
            // 且类的层级越高其属性会被越优先注入
			elements.addAll(0, currElements);
			targetClass = targetClass.getSuperclass();
		}
		while (targetClass != null && targetClass != Object.class);

		//9. 将所有的@Autowired或@Value的属性和方法封装成InjectionMetadata类,并返回
		return new InjectionMetadata(clazz, elements);
	}
  1. 声明一个名为currElements的LinkedList,用于存储metadata
  2. ReflectionUtils.doWithLocalFields()方法的功能为:利用反射获取该类的所有field,并将field作为参数调用doWith(field)方法
	public static void doWithLocalFields(Class<?> clazz, FieldCallback fc) {
		//1. 利用反射获取该类的所有field,并遍历
		for (Field field : getDeclaredFields(clazz)) {
			try {
				//2. 将field作为参数调用doWith(field)方法
				fc.doWith(field);
			}
			catch (IllegalAccessException ex) {
				throw new IllegalStateException("Not allowed to access field '" + field.getName() + "': " + ex);
			}
		}
	}
  1. findAutowiredAnnotation(field)用于查看属性field是否是@AutoWired或者@Value:
	private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
		if (ao.getAnnotations().length > 0) {
			//1. this.autowiredAnnotationTypes中包含了@AutoWired或者@Value
			for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
				//2. 借助AnnotatedElementUtils查看ao总是否有注解为type的属性
				AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
				if (attributes != null) {
					return attributes;
				}
			}
		}
		return null;
	}

在这里插入图片描述

  1. 满足条件的field会被添加到之前声明的currElements中。
  2. 5-7步是将方法添加到currElements中,过程和2-4步基本相同(本文不关注method的处理)
  3. 在解析完Bean的类型之后,需要递归的解析其父类

这样,该bean下的所有@AutoWired和@Value的属性或方法都一起被封装成InjectionMetadata类
总结一下,流程图如下:
在这里插入图片描述
.

3.2 注入metadata到bean中

InjectionMetadata类中的inject()方法:

	public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
		//1. 获取metadata中的InjectedElement集合(3.1小节中生成的就是这个集合)
		Collection<InjectedElement> elementsToIterate =
				(this.checkedElements != null ? this.checkedElements : this.injectedElements);
		if (!elementsToIterate.isEmpty()) {
			boolean debug = logger.isDebugEnabled();
			//2. 遍历集合,对每个元素都调用inject()方法
			for (InjectedElement element : elementsToIterate) {
				if (debug) {
					//debug日志
				}
				element.inject(target, beanName, pvs);
			}
		}
	}

因为element 有不同的子类,因此inject()得具体看是哪个类,以属性为例,会调用AutowiredFieldElement类的inject()方法:

private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
	@Override
		protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
			//1. 取出属性(本次为messageService)
			Field field = (Field) this.member;
			Object value;
			if (this.cached) {
				value = resolvedCachedArgument(beanName, this.cachedFieldValue);
			}
			else {
				//2. 将属性(本次为messageService)封装到DependencyDescriptor中
				DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
				desc.setContainingClass(bean.getClass());
				Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);
				TypeConverter typeConverter = beanFactory.getTypeConverter();
				try {
				//3. 进行解析,参数beanName为属性的拥有类autoWiredBean,desc包含了属性messageService
				// 最后会得到属性的具体实例value(本次为MessageServiceImpl的实例)
					value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
				}
				catch (BeansException ex) {
					throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
				}
				synchronized (this) {
					if (!this.cached) {
						if (value != null || this.required) {
							this.cachedFieldValue = desc;
							//4.注册bean(本文为autoWiredBean)与autowired的属性(本文为messageService)的依赖关系
							registerDependentBeans(beanName, autowiredBeanNames);
							
						//忽略一些代码
						this.cached = true;
					}
				}
			}
			//5. 使用反射,将value(MessageServiceImpl的实例)注入到bean(autoWiredBean)的field(messageService)中
			if (value != null) {
				ReflectionUtils.makeAccessible(field);
				field.set(bean, value);
			}
		}
	}
}
3.2.1 解析依赖关系,得到属性的实例 resolveDependency():
	@Override
	public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
			Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {

		//...忽略一些代码
		else {
			//如果字段上带有@Lazy注解,表示进行懒加载
			//Spring不会立即创建注入属性的实例,而是生成代理对象,来代替实例
			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
					descriptor, requestingBeanName);
			if (result == null) {
				//最后会进入doResolveDependency()方法
				result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
	}

接着看doResolveDependency(): 这里参考了Spring源码:bean创建(五)解决依赖的讲解。

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

		InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
		try {
			//1. 第一次创建时,会保存beanName对应的shotcut用于缓存,这样之后再访问时可以直接获得
			Object shortcut = descriptor.resolveShortcut(this);
			if (shortcut != null) {
				return shortcut;
			}
			//2. 获得属性的类型(本次为“interface com.test.MessageService”)
			Class<?> type = descriptor.getDependencyType();
			
			//3. 处理@Value
			//3.1 获取@Value中的值value
			Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
			if (value != null) {
				//3.2 解析value
				if (value instanceof String) {
					String strVal = resolveEmbeddedValue((String) value);
					BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
					value = evaluateBeanDefinitionString(strVal, bd);
				}
				//3.3 value转换类型后返回
				TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
				return (descriptor.getField() != null ?
						converter.convertIfNecessary(value, type, descriptor.getField()) :
						converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
			}
			//4. 处理数组和Collections类型
			//因为是数组或容器,Sprng可以直接把符合类型的bean都注入到数组或容器中,处理逻辑是:
			//4.1 确定容器或数组的组件类型
			//4.2 调用findAutowireCandidates方法,获取与组件类型匹配的Map(beanName -> bean实例)
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				return multipleBeans;
			}

			//5. 对非数组、容器对象的处理:调用findAutowireCandidates
			//获取所有类型匹配的Map(beanName -> beanClass)
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			
			//6. 结果为空的时候,如果设置的是required,也要抛出异常
			if (matchingBeans.isEmpty()) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				return null;
			}

			String autowiredBeanName;
			Object instanceCandidate;

			//如果类型匹配的bean不止一个,Spring需要进行筛选,本文只有一个MessageServiceImpl,因此略
			if (matchingBeans.size() > 1) {
				autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
				//为空时和上面一样判断,在这里忽略代码
				instanceCandidate = matchingBeans.get(autowiredBeanName);
			}
			else {
				//只有一个bean与类型匹配,那么直接使用该bean
				Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
				autowiredBeanName = entry.getKey();
				instanceCandidate = entry.getValue();
			}

			if (autowiredBeanNames != null) {
				autowiredBeanNames.add(autowiredBeanName);
			}
			//6. 实际上,findAutowireCandidates()方法返回的map中,value一定是class类型(不清楚为什么要这么做,明明已经得到实例了),
			// 所以还要调用BeanFactory的getBean()方法来获得实例。
			return (instanceCandidate instanceof Class ?
					descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);
		}
		finally {
			ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
		}
	}

因为上面的代码比较长,所以在这里总结一下,主要有以下几步:

  1. 获得属性对应的类型Class
  2. 处理@Value
  3. 处理数组或Collections(也就是多个对象)类型
  4. 处理非数组(单个对象)类型:调用findAutowireCandidates()获得。
  5. 确认beanName和bean对象
  6. 返回
3.2.2 @Value解析
3.2.2.1 获取@Value中的值value

先看这个代码

//3.1 获取@Value中的值value
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);

QualifierAnnotationAutowireCandidateResolver.class

	@Override
	public Object getSuggestedValue(DependencyDescriptor descriptor) {
		//descriptor中存储了属性的注解@Value
		//将其作为参数传递给了findValue()方法
		Object value = findValue(descriptor.getAnnotations());
		//找不到的话,就从方法的参数找
		if (value == null) {
			MethodParameter methodParam = descriptor.getMethodParameter();
			if (methodParam != null) {
				value = findValue(methodParam.getMethodAnnotations());
			}
		}
		return value;
	}

	protected Object findValue(Annotation[] annotationsToSearch) {
		//1.在findValue()方法中,使用了AnnotatedElementUtils.getMergedAnnotationAttributes()方法来获取注解的属性attr("value" -> "${xxx}")
		AnnotationAttributes attr = AnnotatedElementUtils.getMergedAnnotationAttributes(
				AnnotatedElementUtils.forAnnotations(annotationsToSearch), this.valueAnnotationType);
		//2.使用extractValue()方法获取key为@Value对应的值
		if (attr != null) {
			return extractValue(attr);
		}
		return null;
	}
  1. descriptor中存储了属性的注解@Value,将其作为参数传递给了findValue()方法
  2. 在findValue()方法中,使用了AnnotatedElementUtils.getMergedAnnotationAttributes()方法来获取注解的属性attr(“value” -> “${xxx}”)
  3. 使用extractValue()方法获取key为@Value对应的值 “${xxx}”
3.2.2.2 解析@Value

解析部分主要需要看一下resolveEmbeddedValue()方法:

	@Override
	public String resolveEmbeddedValue(String value) {
		if (value == null) {
			return null;
		}
		String result = value;
		//寻找StringValueResolver,调用resolveStringValue()进行解析
		for (StringValueResolver resolver : this.embeddedValueResolvers) {
			result = resolver.resolveStringValue(result);
			if (result == null) {
				return null;
			}
		}
		return result;
	}

接着来到了容器AbstractApplicationContext类中,可以看到容器中往beanFactory添加了一个StringValueResolver,而在实现中依靠的是environment来对String进行解析:

		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
				@Override
				public String resolveStringValue(String strVal) {
					//依靠environment来对String进行解析
					return getEnvironment().resolvePlaceholders(strVal);
				}
			});
		}

接着是AbstractEnvironment.class:

	@Override
	public String resolvePlaceholders(String text) {
		return this.propertyResolver.resolvePlaceholders(text);
	}

再接着走到了AbstractPropertyResolver。

	@Override
	public String resolvePlaceholders(String text) {
		if (this.nonStrictHelper == null) {
			this.nonStrictHelper = createPlaceholderHelper(true);
		}
		return doResolvePlaceholders(text, this.nonStrictHelper);
	}
	
	private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) {
		//strictHelper.replacePlaceholders会将"${xxx}"解析成"xxx",
		//并将"xxx"作为参数placeholderName
		return helper.replacePlaceholders(text, new PropertyPlaceholderHelper.PlaceholderResolver() {
			@Override
			public String resolvePlaceholder(String placeholderName) {
				return getPropertyAsRawString(placeholderName);
			}
		});
	}

接着走会走到PropertySourcesPropertyResolver的getPropertyAsRawString()方法:

	@Override
	protected String getPropertyAsRawString(String key) {
		return getProperty(key, String.class, false);
	}

		protected <T> T getProperty(String key, Class<T> targetValueType, boolean resolveNestedPlaceholders) {
		if (this.propertySources != null) {
			// 1. 遍历this.propertySources
			for (PropertySource<?> propertySource : this.propertySources) {
				//打印一些日志,略
				//从propertySource中寻找key
				Object value = propertySource.getProperty(key);
				if (value != null) {
					if (resolveNestedPlaceholders && value instanceof String) {
						value = resolveNestedPlaceholders((String) value);
					}
					//调用ConversionService来将value转化为指定类型,并返回
					return convertValueIfNecessary(value, targetValueType);
				}
			}
		}
		if (logger.isDebugEnabled()) {
			logger.debug("Could not find key '" + key + "' in any property source");
		}
		return null;
	}

到这就能清楚地发现,@Value的解析实际上就是去environment.propertySources中(PropertySourcesPropertyResolver属于environment的一部分)寻找哪个propertySource中含有目标key对应的value。 这么设计的原因是所有指定的properties文件都会提前配置到environment中,感兴趣的小伙伴,传送门:spring 之 PropertySource和Environment

3.2.2.3 @Value解析流程图

在这里插入图片描述

3.2.3 @AutoWired解析
3.2.3.1 多个对象的解析

多个对象的解析实际上就是根据不同的情况获取内部成员的type,然后再调用findAutowireCandidates()来解析type。

	private Object resolveMultipleBeans(DependencyDescriptor descriptor, String beanName,
			Set<String> autowiredBeanNames, TypeConverter typeConverter) {
		Class<?> type = descriptor.getDependencyType();
		//1. 如果是Array类型,则通过type.getComponentType()就能够获取内部成员类的类型
		if (type.isArray()) {
			Class<?> componentType = type.getComponentType();
			//...忽略一些代码
			//调用findAutowireCandidates()
			Map<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(), type);
			if (getDependencyComparator() != null && result instanceof Object[]) {
				Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans));
			}
			return result;
		}
		//2. 如果是Collection类型,则通过descriptor来获得内部的泛型类型
		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));
			//。。。后续操作同上
			return result;
		}
		//3. 如果是map类型,则通过descriptor来获得key的类型和value的类型,不过最后只需要value的类型
		else if (Map.class == type) {
			ResolvableType mapType = descriptor.getResolvableType().asMap();
			Class<?> keyType = mapType.resolveGeneric(0);
			if (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));
			//。。。
			return matchingBeans;
		}
		else {
			return null;
		}
	}
3.2.3.2 单个对象的解析:findAutowireCandidates()

实际上,findAutowireCandidates()方法就是根据目标bean的类型(可能是接口)从BeanFactoryUtils中获取所有的候选BeanNames,然后生成beanName的对应实例bean(正常情况下是从SingletonObjectsMap中直接获得)后,将真正的bean类型(这里就会是实现类)存入到一个map(beanName->beanClass)中并返回。

protected Map<String, Object> findAutowireCandidates(
			String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
		//1. 获取requiredType匹配的所有beanName列表,为了和参数的beanName(参数的是autoWiredBean)区分
		//因此命名为candidateNames
		String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
				this, requiredType, true, descriptor.isEager());
		//2. 建立一个map,用于存储结果,key为candidate(“messageServiceImpl”),value为bean(“MessageServiceImpl”)
		Map<String, Object> result = new LinkedHashMap<String, Object>(candidateNames.length);
		//...特殊类型时,也要存,代码略
		
		for (String candidate : candidateNames) {
			//3. 自引用和其他的判断,略
			if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
				//4. 从singletonObjectMap中取出candidate和requiredType对应的实例,
				// 然后将实例真正的class对象存入第二步建立的map中
				addCandidateEntry(result, candidate, descriptor, requiredType);
			}
		}
			//。。。忽略一些代码
		}
		return result;
	}
3.2.3.2.1 获取requiredType匹配的所有beanName
	public static String[] beanNamesForTypeIncludingAncestors(
			ListableBeanFactory lbf, Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {

		//获得beanNames实际上是通过调用beanFactory的getBeanNamesForType()方法。
		String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
		//如果beanFactory是HierarchicalBeanFactory,则会递归寻找bean的父类
		if (lbf instanceof HierarchicalBeanFactory) {
			HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
			if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
				String[] parentResult = beanNamesForTypeIncludingAncestors(
						(ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);
				List<String> resultList = new ArrayList<String>();
				resultList.addAll(Arrays.asList(result));
				for (String beanName : parentResult) {
					if (!resultList.contains(beanName) && !hbf.containsLocalBean(beanName)) {
						resultList.add(beanName);
					}
				}
				result = StringUtils.toStringArray(resultList);
			}
		}
		return result;
	}

调用getBeanNamesForType,接着会调用doGetBeanNamesForType(),这个方法是获取beanNames的方法:

	private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {

		List<String> result = new ArrayList<String>();
		//1. 遍历beanDefinitionNames
		for (String beanName : this.beanDefinitionNames) {
			if (!isAlias(beanName)) {
				try {
					//2. 获取beanName对应的beanDefinition
					RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
					if (!mbd.isAbstract() && (allowEagerInit ||
							((mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading())) &&
									!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
						// 2. 判断该bean是否是FactoryBean,如果是的话,beanName前面要加上'&'
						boolean isFactoryBean = isFactoryBean(beanName, mbd);
						BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
						boolean matchFound =
								(allowEagerInit || !isFactoryBean ||
										(dbd != null && !mbd.isLazyInit()) || containsSingleton(beanName)) &&
								(includeNonSingletons ||
										(dbd != null ? mbd.isSingleton() : isSingleton(beanName))) &&
								//3. 调用isTypeMatch进行类型匹配
								isTypeMatch(beanName, type);
						if (!matchFound && isFactoryBean) {
							beanName = "&" + beanName;
							matchFound = (includeNonSingletons || mbd.isSingleton()) && isTypeMatch(beanName, type);
						}
						if (matchFound) {
							//4. 添加结果
							result.add(beanName);
						}
					}
				}
		//...忽略catch代码
}

可以看到,实际上获取type匹配的所有beanName,就是从beanDefinitionNames中获取所有已经注册好的的beanName,然后一个一个去尝试匹配,因此可以看出,AutowiredAnnotationBeanPostProcessor这个后置处理器进行处理的前提条件是spring已经将所有的bean都注册到容器上了。
同时,因篇幅有限,在这里就不介绍isTypeMatch()方法了。

3.2.3.2.1 生成candidateName

接下来讲addCandidateEntry()方法:

	private void addCandidateEntry(Map<String, Object> candidates, String candidateName,
			DependencyDescriptor descriptor, Class<?> requiredType) {
		//1. 将结果(candidateName->candidateObject)存放到结果map中。
		//2. 特殊情况下,直接调用beanFactory.getBean(beanName, requiredType);来获得结果
		if (descriptor instanceof MultiElementDescriptor || containsSingleton(candidateName)) {
			candidates.put(candidateName, descriptor.resolveCandidate(candidateName, requiredType, this));
		}
		else {
			//3.正常情况下,调用getType(candidateName)来获得candidate
			candidates.put(candidateName, getType(candidateName));
		}
	}

接着看getType()方法:

	@Override
	public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
		String beanName = transformedBeanName(name);

		//1.getSingleton()实际上是从singletonObjectMap中获得目标对象
		Object beanInstance = getSingleton(beanName, false);
		//2.不为空时,根据是bean还是factoryBean来返回
		if (beanInstance != null) {
			if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
				return getTypeForFactoryBean((FactoryBean<?>) beanInstance);
			}
			else {
				return beanInstance.getClass();
			}
		}
		else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
			// null instance registered
			return null;
		}

		//3. 没有找到bean时 --> 尝试从父BeanFactory中获取
		BeanFactory parentBeanFactory = getParentBeanFactory();
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			return parentBeanFactory.getType(originalBeanName(name));
		}

		RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

		//忽略一些代码

		//4. 直接将BeanDefinition的TargetType作为beanClass
		Class<?> beanClass = predictBeanType(beanName, mbd);
		//不为空时,根据是bean还是factoryBean来返回
		if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) {
			if (!BeanFactoryUtils.isFactoryDereference(name)) {
				return getTypeForFactoryBean(beanName, mbd);
			}
			else {
				return beanClass;
			}
		}
		else {
			return (!BeanFactoryUtils.isFactoryDereference(name) ? beanClass : null);
		}
	}

最后再来看一下getSingleton():

	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// 从singletonObjectMap中获得目标对象
		Object singletonObject = this.singletonObjects.get(beanName);
		//...忽略一些代码
		return (singletonObject != NULL_OBJECT ? singletonObject : null);
	}

可以看到,目标对象实际上是从SingletonObjectsMap中获得的,对于工厂来说,则还需要调用getObject()来获得目标对象。

3.2.3.3 @AutoWired解析总结

到这里就全部讲解完毕了,现在我们先总结一下@AutoWired解析的解析流程:
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值