spring源码分享之容器系列三(spring的依赖注入)

spring的依赖注入是spring的依赖的一个很重要的特性,本文详细介绍了spring在进行属性注入的几种方式以及spring源码中是怎么完成这些属性注入的。

AbstractAutowireCapableBeanFactory#populateBean

spring中对属性的赋值操作主要是在populateBean这个方法来完成的。可以看到这个populateBean主要做了四件事。

  1. 调用InstantiationAwareBeanPostProcessor 的afterInstantiation方法
  2. 直接通过PropertyDescriptor中获取相应的属性名或者属性类型来进行注入
  3. 调用postProcessPropertyValues方法进行注入(@Autowired注解在此处进行注入)
  4. 将PropertyValues数据赋值到对应的bean(RuntimeBeanReference在此处解析)

这四件事中第一件事调用afterInstantiation主要是正在属性赋值之前进行的操作,其提供了一个返回值标识是否需要进行后续的属性赋值。第二件事则是通过属性名或者属性类型来直接进行赋值,这种赋值方式则需要将依赖注入方式配置为AUTOWIRE_BY_NAME或者AUTOWIRE_BY_TYPE这两种方式,默认配置的bean是AUTOWIRE_NO,即不会进行这种方式的注入,而第三件事则是调用InstantiationAwareBeanPostProcessor postProcessPropertyValues方法来进行属性处理,这种方式提供了外部属性赋值的扩展,并且@Autowired等注解的注入实现则是在此处完成的,最后则是将PropertyValues利用BeanWraper赋值到对应的bean,不过在具体赋值之前会将RuntimeBeanReference这些配置中的ref这些标识beanName的属性从beanFactory中获取对应的bean。

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
		PropertyValues pvs = mbd.getPropertyValues();

		... //检查bw空

		//调用afterInstantiation这个process,
		//表示不止在doCreateBean这个创建bean的方法会调用afterInstantiation
		//对于autowireBean这些依赖注入的方法也会调用其生命周期中的afterInstantiation
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						return;
					}
				}
			}
		}
		//直接根据属性来进行注入
		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			//直接根据属性名查询对应的bean
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			//直接根据属性类型查询对应的bean
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}
		//利用postProcessPropertyValues方法提供外部对属性的注入操作
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
		if (hasInstAwareBpps || needsDepCheck) {
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			if (hasInstAwareBpps) {
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						//@Autowire则是通过此处进行注册的
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvs == null) {
							return;
						}
					}
				}
			}
			if (needsDepCheck) {
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}
		//进行属性赋值,主要是对RuntimeBeanReference这些运行时的数据进行相应的处理
		applyPropertyValues(beanName, mbd, bw, pvs);
	}

可以看到对于依赖注入其对应的依赖的bean的获取方式主要是三种:

  1. 直接利用bean中的属性名或者属性类型获取对应的bean注入到PropertyValues中
  2. 利用@Autowired和@Value注解直接利用Filed的反射进行bean的属性赋值
  3. 通过配置最终注入到PropertyValues中

1.AUTOWIRE_BY_NAME或者AUTOWIRE_BY_TYPE方式注入

这种方式的注入方式主要是在BeanDefinition的配置中将其autowireMode配置为byName或者byType类型,即下面这种配置方式。主要在autowire配置为byName或者byType。


	
	
	
	
public class TestBean {
	private TestDe1 t1 ; 
	private TestDe2 t2 ;
	public TestDe1 getT1() {
		return t1;
	}
	public void setT1(TestDe1 t1) {
		this.t1 = t1;
	}
	public TestDe2 getT2() {
		return t2;
	}
	public void setT2(TestDe2 t2) {
		this.t2 = t2;
	} 
}
public class TestDe1 {
}
public class TestDe2 {
}

这种注入的主要的对应的实现是在autowireByName和autowireByType方法中进行实现的,下面来详细介绍一下这两个方法。

autowireByName

可以看到这个方法的对应的主要逻辑是获取属性中满足条件的名字,并且通过名字获取对应的bean,将其加入到PropertyVaules中,并将对应的依赖关系注册到容器中。

protected void autowireByName(
		String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
	//获取mbd中的pvs没有数据,并且不是简单类,并且不是cglib定义的类,
	//并且不是ignoredDependencyTypes中的类型,并且不是ignoredDependencyInterfaces的方法
	//的对应的属性名称
	String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
	//直接用属性名作为beanName找其对应的bean注入
	for (String propertyName : propertyNames) {
		if (containsBean(propertyName)) {
			Object bean = getBean(propertyName);
			pvs.add(propertyName, bean);
			//注册dependentBean
			registerDependentBean(propertyName, beanName);
			...
		}
		else {
			...
		}
	}
}

autowireByType

这个方法和autowireByName方法类似,其主要的区别是autowireByName是直接可以通过name从beanFactory获取对应的bean,而对于autowireByType则是利用resolveDependency来解析对应类型的bean。

protected void autowireByType(
		String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

	TypeConverter converter = getCustomTypeConverter();
	if (converter == null) {
		converter = bw;
	}
	Set autowiredBeanNames = new LinkedHashSet(4);
	String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
	for (String propertyName : propertyNames) {
		try {
			PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
			if (Object.class != pd.getPropertyType()) {
				MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
				// Do not allow eager init for type matching in case of a prioritized post-processor.
				boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
				DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
				//查询对应的依赖
				Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
				if (autowiredArgument != null) {
					pvs.add(propertyName, autowiredArgument);
				}
				//注册依赖
				for (String autowiredBeanName : autowiredBeanNames) {
					registerDependentBean(autowiredBeanName, beanName);
				}
				autowiredBeanNames.clear();
			}
		}
		catch (BeansException ex) {
			throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
		}
	}
}

DefaultListableBeanFactory#resolveDependency

这里分了几种特殊类型的需要解析的type,对其进行了不同程度的包装,不过最终执行的操作都是doResolveDependency来完成对应的依赖的解析。

@Override
public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
		Set autowiredBeanNames, TypeConverter typeConverter) throws BeansException {

	descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
	if (javaUtilOptionalClass == descriptor.getDependencyType()) {
		return new OptionalDependencyFactory().createOptionalDependency(descriptor, requestingBeanName);
	}
	else if (ObjectFactory.class == descriptor.getDependencyType() ||
			ObjectProvider.class == descriptor.getDependencyType()) {
		return new DependencyObjectProvider(descriptor, requestingBeanName);
	}
	else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
		return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
	}
	else {
		//这里对于@Lazy注解是会创建一个代理,在真正用到对应的依赖的bean时在进行对应的依赖解析
		Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
				descriptor, requestingBeanName);
		if (result == null) {
			//真正的进行依赖解析
			result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
		}
		return result;
	}
}

doResolveDependency 

可以看到这个方法中的依赖的获取方式主要有三种:

  1. 从DependencyDescriptor的的缓存中获取:像AutowiredAnnotationBeanPostProcessor这种对带有@Autowired注解的属性或者方法通过类型解析出符合的beanName时会将beanName存储到ShortcutDependencyDescriptor这种DependencyDescriptor中,下次再需要解析时则可直接利用这个缓存的beanName获取。
  2. 从AutowireCandidateResolver中获取推荐的值:像QualifierAnnotationAutowireCandidateResolver这种类型的解析器会解析对应的filed或者method上的@Value注解来作为其对应的依赖的对象。
  3. 从当前beanFactory中获取这个类型的对应的bean:根据类型查询这个类型下符合要求的bean主要是对注册进入的beanDefinition对应的bean以及注册进的单例的bean的类型进行类型比较。找到符合的bean。

对于从beanFactory查询的对应类型的beanName,如果需要注入的是集合,则可以直接将结合直接返回,如果不是则则根据是否有唯一的配置了primary或者是否有最高优先级的bean来确定唯一的bean进行返回。

public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
		Set autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
	InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
	try {
	    //对于ShortcutDependencyDescriptor实现了这个方法,主要是对在DependencyDescriptor中直接可以进行缓存解析的返回对应的值
		//像AutowiredAnnotationBeanPostProcessor则会创建ShortcutDependencyDescriptor缓存对应的beanName
		Object shortcut = descriptor.resolveShortcut(this);
		if (shortcut != null) {
			return shortcut;
		}
		Class type = descriptor.getDependencyType();
		//主要是作为methodParameter时其对应的method上的@Value注解可以获取对应的值
		Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
		if (value != null) {
			if (value instanceof String) {
			    //利用StringValueResolver解析对应的字符串
				String strVal = resolveEmbeddedValue((String) value);
				BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
				//利用beanExpressionResolver解析对应的字符串
				value = evaluateBeanDefinitionString(strVal, bd);
			}
			//利用TypeConverter进行类型转换
			TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
			return (descriptor.getField() != null ?
					converter.convertIfNecessary(value, type, descriptor.getField()) :
					converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
		}
        //处理List,Set这种集合形式的注入
		Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
		if (multipleBeans != null) {
			return multipleBeans;
		}
        //获取type类型的所有候选的bean
        //这里获取可能是对象,也有可能是对应的bean的类型
		Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
		if (matchingBeans.isEmpty()) {
		    //没有数据但是是required则抛出异常
			if (isRequired(descriptor)) {
				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
			}
			return null;
		}
		String autowiredBeanName;
		Object instanceCandidate;
		if (matchingBeans.size() > 1) {
		      //确定唯一的对应类型的bean,主要是检查primary或者实现了OrderComparator找highestPriority的bean
			autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
			if (autowiredBeanName == null) {
			    //是必须的并且不是List这种集合形式的,则有descriptor尝试处理不唯一的情况
				if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
					return descriptor.resolveNotUnique(type, matchingBeans);
				}
				else {
					return null;
				}
			}
			//选择对应的值
			instanceCandidate = matchingBeans.get(autowiredBeanName);
		}
		else {
			// 只有一个匹配的则直接选这个
			Map.Entry entry = matchingBeans.entrySet().iterator().next();
			autowiredBeanName = entry.getKey();
			instanceCandidate = entry.getValue();
		}
		if (autowiredBeanNames != null) {
			autowiredBeanNames.add(autowiredBeanName);
		}
		//这里的instanceCandidate可能只是类型,所有需要进行resolveCandidate操作,获取真正的实例
		return (instanceCandidate instanceof Class ?
				descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);
	}
	finally {
		ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
	}
}

 findAutowireCandidates

这个方法可以看到对应的依赖的beanName主要是从resolvableDependencies配置的bean,或者利用type查找到所有符合这个类型的beanName中查找,不过这些候选beanName主要进行三种限制:

  1. 依赖的bean不是当前的beanName对应的bean
  2. 对应的依赖的bean的泛型和当前属性的泛型是否匹配
  3. @Qulifier的相应的检查
protected Map findAutowireCandidates(
		String beanName, Class requiredType, DependencyDescriptor descriptor) {
	//查询这个type下所有的beanName,其主要是调用所有的本地beanFactory以及父beanFactory	
	String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
			this, requiredType, true, descriptor.isEager());
	Map result = new LinkedHashMap(candidateNames.length);
	//从resolvableDependencies中进行对应的依赖查找
	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 candidate : candidateNames) {
	    //beanName和candidate是一样的
	    //或者对应的baneName或者factoryBean的对应的beanName是一样的
		if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
		    //将对应的类型或者对应的bean加入到result中
			addCandidateEntry(result, candidate, descriptor, requiredType);
		}
	}
	//利用fallbackDescriptor再做一次尝试
	if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) {
		DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
		for (String candidate : candidateNames) {
			//isAutowireCandidate这里主要做了泛型的检查(如Bean,和Bean的类型都是Bean,但是不应该能作为对应的依赖),以及@Qualifier的检查
			if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor)) {
				addCandidateEntry(result, candidate, descriptor, requiredType);
			}
		}
		//对isSelfReference放宽限制不检查factoryMethod对应的bean
		if (result.isEmpty()) {
			for (String candidate : candidateNames) {
				if (isSelfReference(beanName, candidate) &&
						(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
						isAutowireCandidate(candidate, fallbackDescriptor)) {
					addCandidateEntry(result, candidate, descriptor, requiredType);
				}
			}
		}
	}
	return result;
}

2.@Autowired,@Value注解注入

对于@Autowired和@Value的注入主要是利用AutowiredAnnotationBeanPostProcessor这个BeanPostProcessor来完成的。其主要的注入逻辑实在postProcessPropertyValues方法中,具体的配置方式为。

public class TestBean {
	@Autowired
	private TestDe1 t1 ;
	@Value("t2")
	private TestDe2 t2 ;
	public TestDe1 getT1() {
		return t1;
	}
	public void setT1(TestDe1 t1) {
		this.t1 = t1;
	}
	public TestDe2 getT2() {
		return t2;
	}
	public void setT2(TestDe2 t2) {
		this.t2 = t2;
	} 
}

AutowiredAnnotationBeanPostProcessor

AutowiredAnnotationBeanPostProcessor主要是对@Autowired和@Value这两个注解下的属性和方法进行相应的注入操作,并对@Lookup下的方法注册lookup-method的操作,并且根据@Autowired或@Value决定相应的构造器的操作。

其下维护的属性中injectionMetadataCache主要是维护了有@Autowired和@Value注解的对应的方法或属性的meta数据,最终的属性注入则是利用InjectionMetadata进行操作。candidateConstructorCache则是对对应的beanClass中的选择的Constructor的缓存。lookupMethodsChecked则是表示的是beanName的对应的bean是否检查了对应的@Lookup的注解

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
		implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
    
	private final Set> autowiredAnnotationTypes =
 			new LinkedHashSet>(4);
	//它的排序是最后-2,而RequiredAnnotationBeanPostProcessor是-1
	//表示这个beanPostProcessor默认是排在RequiredAnnotationBeanPostProcessor前面
	private int order = Ordered.LOWEST_PRECEDENCE - 2;
	private ConfigurableListableBeanFactory beanFactory;
	//标识对应的beanName是否检查了@lookup注解
	private final Set lookupMethodsChecked =
			Collections.newSetFromMap(new ConcurrentHashMap(256));
	//beanClass-->Constructor[] 的缓存
	private final Map, Constructor[]> candidateConstructorsCache =
			new ConcurrentHashMap, Constructor[]>(256);
	//beanName-->InjectionMetadata 注册的对应的metadata的缓存
	private final Map injectionMetadataCache =
			new ConcurrentHashMap(256);
}

postProcessPropertyValue和postProcessMergedBeanDefinition

其posrProcessPropertyValues方法逻辑其实很简单,就是将当前beanName和beanClass直接获取对应的InjectionMetadata这个meta,然后将其对应的注入操作委托给这个metadata数据,这个InjectionMetadata其实是通过解析对应的class中属性和方法是否有@Value,@Autowired等注解,并将每个属性或者方法解析为InjectedElement,最终是利用这些InjectedElement来进行注入操作。

postProcessMergedBeanDefinition方法也是获取InjectionMetadata,然后调用InjectionMetadata的checkConfigMembers方法来确定

 

@Override
public PropertyValues postProcessPropertyValues(
		PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
	
	InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
	try {
		metadata.inject(bean, beanName, pvs);
	}
	catch (BeanCreationException ex) {
		... throw
	}
	return pvs;
}

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) {
	if (beanType != null) {
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}
}

InjectionMetadata

InjectionMetadata其实主要是维护了injectedElementscheckedElements这两个集合,其中injectedElements集合是注入的,而checkedElements这个集合则是方法checkConfigMembers这个方法调用时将InjectedElement中的field或者method注册到beanDefinition成功时加入的,主要作用应该是防止对相应的属性的重复注入。最终对field或method的注入也是InjectedElement来完成的

public class InjectionMetadata {
	//目标class
	private final Class targetClass;
	//从targetClass解析出的IbjectedElement
	private final Collection injectedElements;
	//调用checkConfigMembers加入的真正的调用的InjectedElement
	private volatile Set checkedElements;
	//主要是过滤beanDefinition中已经注册了的属性或者对象
	public void checkConfigMembers(RootBeanDefinition beanDefinition) {
		Set checkedElements = new LinkedHashSet(this.injectedElements.size());
		for (InjectedElement element : this.injectedElements) {
			Member member = element.getMember();
			if (!beanDefinition.isExternallyManagedConfigMember(member)) {
				beanDefinition.registerExternallyManagedConfigMember(member);
				checkedElements.add(element);
			}
		}
		this.checkedElements = checkedElements;
	}
	//对经历了checkConfigMembers的使用checkedElements集合中的InjectedElement进行处理
	//否则用注册的injectedElements进行处理
	public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
		Collection elementsToIterate =
				(this.checkedElements != null ? this.checkedElements : this.injectedElements);
		if (!elementsToIterate.isEmpty()) {
			for (InjectedElement element : elementsToIterate) {
				element.inject(target, beanName, pvs);
			}
		}
	}
}

AutowiredFieldElement 

AutowiredFieldElementAutowiredMethodElement是两个最终执行注入操作的InjectedElement的子类,其主要是通过filed,或者方法中的methodParameter构建出DependencyDescriptor利用beanFactory获取对应的依赖bean,并对其进行缓存,依赖关系注册到beanFactory以及进行属性赋值的操作。

这里是直接进行属性和方法赋值,而不是将依赖bean放入到PropertyValues中,因此对属性的注入不需要get,set方法,并且也不会走BeanWrapperImpl属性赋值的类型转换逻辑,并且@Required等注解的检查还是会生效。

可以看到这里也是通过type获取对应的依赖bean,其最终获取其依赖的bean还是通过 resolveDependency来完成的。

private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
	//是否必须
	private final boolean required;
	//是否已经缓存标志
	private volatile boolean cached = false;
	//缓存的DependencyDescriptor
	private volatile Object cachedFieldValue;

	@Override
	protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
		Field field = (Field) this.member;
		Object value;
		if (this.cached) {
			//利用缓存的DependencyDescriptor从beanFactory中获取对应的依赖bean
			value = resolvedCachedArgument(beanName, this.cachedFieldValue);
		}
		else {
			DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
			desc.setContainingClass(bean.getClass());
			Set autowiredBeanNames = new LinkedHashSet(1);
			TypeConverter typeConverter = beanFactory.getTypeConverter();
			try {
				//通过filed获取对应的依赖bean
				value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
			}
			catch (BeansException ex) {
				... throws
			}
			//缓存处理
			synchronized (this) {
				if (!this.cached) {
					if (value != null || this.required) {
						this.cachedFieldValue = desc;
						//第一次将对应的依赖关系注册到容器中
						registerDependentBeans(beanName, autowiredBeanNames);
						if (autowiredBeanNames.size() == 1) {
							String autowiredBeanName = autowiredBeanNames.iterator().next();
							if (beanFactory.containsBean(autowiredBeanName) &&
									beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
								//这里只有一个候选bean,并且其对应的候选的beanName是当前的bean
								//依赖的类型匹配,则用ShortcutDependencyDescriptor进行缓存,
								//在进行下次依赖查找时直接返回这个beanName
								this.cachedFieldValue = new ShortcutDependencyDescriptor(
										desc, autowiredBeanName, field.getType());
							}
						}
					}
					else {
						this.cachedFieldValue = null;
					}
					this.cached = true;
				}
			}
		}
		if (value != null) {
			ReflectionUtils.makeAccessible(field);
			//这里是直接进行了赋值操作,而不是放入到PropertyValues中
			field.set(bean, value);
		}
	}
}

3.PropertyValues配置注入

对于直接配置的依赖,其主要是在配置时以RuntimeBeanReference,BeanDefinitionHolder等形式存在于PropertyValues的对应的vaule中,并最终在AbstractAutowireCapableBeanFactory#applyPropertyValues下将对应的RuntimeBeanReference解析成对应的bean,下面的配置是对bean的属性的各种类型的配置方式,并用注释标注了其最终在PropertyValues中存在的类型。


	    
	
	    
	    
	    
	      
	      
	          
	          
	      
	    
	    
	      
	      
	          
	          
	           
	      
	    
	    
	    
	      
	          
	           
	      
	    
	    
	    
	      
	         
	      
	    
	     
	     #{1+2}
	     
	     
	        
	           value
	        
	     
	
	
	 
	 
	 
	 
	   
	   
		

applyPropertyValues

applyPropertyValues的主要操作是利用BeanDefinitionValueResolver进行类型转换,并在必要情况下调用TypeConverter进行类型转换操作。

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
	if (pvs == null || pvs.isEmpty()) {
		return;
	}

	MutablePropertyValues mpvs = null;
	List original;

	if (System.getSecurityManager() != null) {
		if (bw instanceof BeanWrapperImpl) {
			((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
		}
	}
	//已经完成转换的直接利用BeanWrapper赋值
	if (pvs instanceof MutablePropertyValues) {
		mpvs = (MutablePropertyValues) pvs;
		if (mpvs.isConverted()) {
			// Shortcut: use the pre-converted values as-is.
			try {
				bw.setPropertyValues(mpvs);
				return;
			}
			catch (BeansException ex) {
				... throw
			}
		}
		original = mpvs.getPropertyValueList();
	}
	else {
		original = Arrays.asList(pvs.getPropertyValues());
	}

	TypeConverter converter = getCustomTypeConverter();
	if (converter == null) {
		converter = bw;
	}
	BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

	//主要操作是利用BeanDefinitionValueResolver进行类型转换
	List deepCopy = new ArrayList(original.size());
	boolean resolveNecessary = false;
	for (PropertyValue pv : original) {
		if (pv.isConverted()) {
			deepCopy.add(pv);
		}
		else {
			String propertyName = pv.getName();
			Object originalValue = pv.getValue();
			Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
			Object convertedValue = resolvedValue;
			boolean convertible = bw.isWritableProperty(propertyName) &&
					!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
			if (convertible) {
				convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
			}
			if (resolvedValue == originalValue) {
				if (convertible) {
					pv.setConvertedValue(convertedValue);
				}
				deepCopy.add(pv);
			}
			else if (convertible && originalValue instanceof TypedStringValue &&
					!((TypedStringValue) originalValue).isDynamic() &&
					!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
				pv.setConvertedValue(convertedValue);
				deepCopy.add(pv);
			}
			else {
				resolveNecessary = true;
				deepCopy.add(new PropertyValue(pv, convertedValue));
			}
		}
	}
	if (mpvs != null && !resolveNecessary) {
		mpvs.setConverted();
	}

	// Set our (possibly massaged) deep copy.
	try {
		bw.setPropertyValues(new MutablePropertyValues(deepCopy));
	}
	catch (BeansException ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Error setting property values", ex);
	}
}

BeanDefinitionValueResolver

BeanDefinitionValueResolver主要是对beanFactory的相应的reference的操作,其主要是利用给的beanName从beanFactory中获取对应的bean。

其主要的操作有三种

  1. 对string进行evaluate:evalueate的主要是利用BeanExpressionResolver进行表达式的计算(即#{1+2}这种类型的字符串的计算),
  2. 从beanFactory获取对应的bean:直接从beanFactory赵铎RuntimeBeanRefrence对应的beanName下的bean.
  3. BeanDefinition:直接根据beanDefinition利用beanFactory创建对应的bean

注意:这里的利用BeanDefinition的方式创建的bean没有注册进入beanFactory中。只是利用beanFactory创建了对应的bean

上面三种主要是最终三种对三种基础类型(string,RuntimeBeanReference,BeanDefinition)进行的操作,其他如ManagedList,ManagedSet这些集合最终都会进行递归调用resolveValueIfNessary这个方法从而转为这几种基础类型进行操作

注意:这里的RuntimeBeanReferenceRuntimeBeanNameReference的主要区别是前一个返回的是bean这个Object对象,而后一个返回的最终还是一个字符串,只是这个字符串进行了是否是beanName的检查以及evaluate操作

public Object resolveValueIfNecessary(Object argName, Object value) {
	if (value instanceof RuntimeBeanReference) {
		RuntimeBeanReference ref = (RuntimeBeanReference) value;
		return resolveReference(argName, ref);
	}
	else if (value instanceof RuntimeBeanNameReference) {
		String refName = ((RuntimeBeanNameReference) value).getBeanName();
		refName = String.valueOf(doEvaluate(refName));
		if (!this.beanFactory.containsBean(refName)) {
			... throw
		}
		return refName;
	}
	else if (value instanceof BeanDefinitionHolder) {
		BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
		return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
	}
	else if (value instanceof BeanDefinition) {
		BeanDefinition bd = (BeanDefinition) value;
		String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
				ObjectUtils.getIdentityHexString(bd);
		return resolveInnerBean(argName, innerBeanName, bd);
	}
	else if (value instanceof ManagedArray) {
		ManagedArray array = (ManagedArray) value;
		Class elementType = array.resolvedElementType;
		if (elementType == null) {
			String elementTypeName = array.getElementTypeName();
			if (StringUtils.hasText(elementTypeName)) {
				try {
					elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
					array.resolvedElementType = elementType;
				}
				catch (Throwable ex) {
					... throw
				}
			}
			else {
				elementType = Object.class;
			}
		}
		return resolveManagedArray(argName, (List) value, elementType);
	}
	else if (value instanceof ManagedList) {
		// May need to resolve contained runtime references.
		return resolveManagedList(argName, (List) value);
	}
	else if (value instanceof ManagedSet) {
		// May need to resolve contained runtime references.
		return resolveManagedSet(argName, (Set) value);
	}
	else if (value instanceof ManagedMap) {
		// May need to resolve contained runtime references.
		return resolveManagedMap(argName, (Map) value);
	}
	//注意这里的properties是不能设置ref这种bean的方式
	else if (value instanceof ManagedProperties) {
		Properties original = (Properties) value;
		Properties copy = new Properties();
		for (Map.Entry propEntry : original.entrySet()) {
			Object propKey = propEntry.getKey();
			Object propValue = propEntry.getValue();
			if (propKey instanceof TypedStringValue) {
				propKey = evaluate((TypedStringValue) propKey);
			}
			if (propValue instanceof TypedStringValue) {
				propValue = evaluate((TypedStringValue) propValue);
			}
			copy.put(propKey, propValue);
		}
		return copy;
	}
	else if (value instanceof TypedStringValue) {
		TypedStringValue typedStringValue = (TypedStringValue) value;
		Object valueObject = evaluate(typedStringValue);
		try {
			Class resolvedTargetType = resolveTargetType(typedStringValue);
			if (resolvedTargetType != null) {
				return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
			}
			else {
				return valueObject;
			}
		}
		catch (Throwable ex) {
			... throw
		}
	}
	else {
		return evaluate(value);
	}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(spring学习笔记)