Spring源码学习-4.IoC.依赖注入

IoC依赖注入

对于IoC容器初始化的过程已经完成了,初始化就是在容器中建立BeanDefinition的数据映射,接下来我们来分析下,Spring是怎么对Bean进行依赖注入的


Bean的初始化一般是在第一次获取这个Bean的时候完成的,也可以设置lazy-init完成预实例化,现在我来看第一次获取时,是怎么样依赖注入的:


依赖注入的开始就是在BeanFactory里面就有的一个方法,getBean().我们来看他在AbstractFactory中是怎么实现的

1.依赖注入的开始,getBean

public Object getBean(String name) throws BeansException {
		return getBean(name, null, null);
	}

public Object getBean(String name, Class requiredType, Object[] args) throws BeansException {
	return doGetBean(name, requiredType, args, false);
}

protected Object doGetBean(
		final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
	//转化name,如果是BeanName就返回BeanName,如果是别名,就从Map中找出对应BeanName返回
	final String beanName = transformedBeanName(name);
	Object bean = null;

	// Eagerly check singleton cache for manually registered singletons.
	//查看缓存中是否有这个实例
	Object sharedInstance = getSingleton(beanName);
	if (sharedInstance != null) {
		if (logger.isDebugEnabled()) {
			if (isSingletonCurrentlyInCreation(beanName)) {
				logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
						"' that is not fully initialized yet - a consequence of a circular reference");
			}
			else {
				logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
			}
		}
		//处理这个Bean
		//如果这是一个普通bean 直接去创建FactoryBean,如果是FactoryBean,直接返回
		//有可能这个实例是返回的父BeanFactory 缓存里面的Bean
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}

	else {
		// Fail if we're already creating this bean instance:
		// We're assumably within a circular reference.
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		// Check if bean definition exists in this factory.
		//检查BeanDefinition是否在Factory中 ,如果找不到就一直找父factory
		BeanFactory parentBeanFactory = getParentBeanFactory();
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			// Not found -> check parent.
			String nameToLookup = originalBeanName(name);
			if (args != null) {
				// Delegation to parent with explicit args.
				return parentBeanFactory.getBean(nameToLookup, args);
			}
			else {
				// No args -> delegate to standard getBean method.
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
		}

		if (!typeCheckOnly) {
			markBeanAsCreated(beanName);
		}
		//根据name获取BeanDefinition
		final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
		checkMergedBeanDefinition(mbd, beanName, args);

		// Guarantee initialization of beans that the current bean depends on.
		//依次加载依靠的BeanDefinition
		String[] dependsOn = mbd.getDependsOn();
		if (dependsOn != null) {
			for (int i = 0; i < dependsOn.length; i++) {
				String dependsOnBean = dependsOn[i];
				getBean(dependsOnBean);
				registerDependentBean(dependsOnBean, beanName);
			}
		}

		// Create bean instance.
		
		if (mbd.isSingleton()) {
			sharedInstance = getSingleton(beanName, new ObjectFactory() {
				public Object getObject() throws BeansException {
					try {
						return createBean(beanName, mbd, args);
					}
					catch (BeansException ex) {
						// Explicitly remove instance from singleton cache: It might have been put there
						// eagerly by the creation process, to allow for circular reference resolution.
						// Also remove any beans that received a temporary reference to the bean.
						destroySingleton(beanName);
						throw ex;
					}
				}
			});
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
		}

		else if (mbd.isPrototype()) {
			// It's a prototype -> create a new instance.
			Object prototypeInstance = null;
			try {
				beforePrototypeCreation(beanName);
				prototypeInstance = createBean(beanName, mbd, args);
			}
			finally {
				afterPrototypeCreation(beanName);
			}
			bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
		}

		else {
			String scopeName = mbd.getScope();
			final Scope scope = (Scope) this.scopes.get(scopeName);
			if (scope == null) {
				throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
			}
			try {
				Object scopedInstance = scope.get(beanName, new ObjectFactory() {
					public Object getObject() throws BeansException {
						beforePrototypeCreation(beanName);
						try {
							return createBean(beanName, mbd, args);
						}
						finally {
							afterPrototypeCreation(beanName);
						}
					}
				});
				bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
			}
			catch (IllegalStateException ex) {
				throw new BeanCreationException(beanName,
						"Scope '" + scopeName + "' is not active for the current thread; " +
						"consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
						ex);
			}
		}
	}
	//检查是否符合类型,这个Bean已经包含依赖关系
	// Check if required type matches the type of the actual bean instance.
	if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
		throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
	}
	return bean;
}

调用里面的createBean这个方法,按照BeanDefinition里面的信息,返回这个Instance

protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
		throws BeanCreationException {

	AccessControlContext acc = AccessController.getContext();
	return AccessController.doPrivileged(new PrivilegedAction() {
		public Object run() {
			if (logger.isDebugEnabled()) {
				logger.debug("Creating instance of bean '" + beanName + "'");
			}
			// Make sure bean class is actually resolved at this point.
			//判定是否可以实例化,是否可以通过加载器实现
			resolveBeanClass(mbd, beanName);

			// Prepare method overrides.
			try {
			//
				mbd.prepareMethodOverrides();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
						beanName, "Validation of method overrides failed", ex);
			}

			try {
				// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
				//如果配置了BeanPostProcessors,返回一个代理
				Object bean = resolveBeforeInstantiation(beanName, mbd);
				if (bean != null) {
					return bean;
				}
			}
			catch (Throwable ex) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"BeanPostProcessor before instantiation of bean failed", ex);
			}
			//创建实例
			Object beanInstance = doCreateBean(beanName, mbd, args);
			if (logger.isDebugEnabled()) {
				logger.debug("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
	}, acc);
}

doCreateBean方法,这里创建Bean

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
	// Instantiate the bean.
	//BeanWrapper是用来持有新创建的Bean的
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = (BeanWrapper) this.factoryBeanInstanceCache.remove(beanName);
	}
	//由CreateBeanInstance方法创建Bean
	if (instanceWrapper == null) {
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
	Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

	// Allow post-processors to modify the merged bean definition.
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			mbd.postProcessed = true;
		}
	}

	// Eagerly cache singletons to be able to resolve circular references
	// even when triggered by lifecycle interfaces like BeanFactoryAware.
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		if (logger.isDebugEnabled()) {
			logger.debug("Eagerly caching bean '" + beanName +
					"' to allow for resolving potential circular references");
		}
		addSingletonFactory(beanName, new ObjectFactory() {
			public Object getObject() throws BeansException {
				return getEarlyBeanReference(beanName, mbd, bean);
			}
		});
	}

	//这里要对Bean进行初始化,依赖注入在此发生
	// Initialize the bean instance.
	Object exposedObject = bean;
	try {
		//初始化
		populateBean(beanName, mbd, instanceWrapper);
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
	catch (Throwable ex) {
		if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
			throw (BeanCreationException) ex;
		}
		else {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
		}
	}

	if (earlySingletonExposure) {
		Object earlySingletonReference = getSingleton(beanName, false);
		if (earlySingletonReference != null) {
			if (exposedObject == bean) {
				exposedObject = earlySingletonReference;
			}
			else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
				String[] dependentBeans = getDependentBeans(beanName);
				Set actualDependentBeans = new LinkedHashSet(dependentBeans.length);
				for (int i = 0; i < dependentBeans.length; i++) {
					String dependentBean = dependentBeans[i];
					if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
						actualDependentBeans.add(dependentBean);
					}
				}
				if (!actualDependentBeans.isEmpty()) {
					throw new BeanCurrentlyInCreationException(beanName,
							"Bean with name '" + beanName + "' has been injected into other beans [" +
							StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
							"] in its raw version as part of a circular reference, but has eventually been " +
							"wrapped. This means that said other beans do not use the final version of the " +
							"bean. This is often the result of over-eager type matching - consider using " +
							"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
				}
			}
		}
	}

	// Register bean as disposable.
	registerDisposableBeanIfNecessary(beanName, bean, mbd);

	return exposedObject;
}

createBeanInstance方法创建了实例

这里有很多种不同的生成方法,如工厂方法,容器autowirs特性等.


	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
		// Make sure bean class is actually resolved at this point.
		//将BeanName转化为ClassName
		Class beanClass = resolveBeanClass(mbd, beanName);
		//使用工厂方法对Bean进行实例化
		if (mbd.getFactoryMethodName() != null)  {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}
		
		// Shortcut when re-creating the same bean...
		if (mbd.resolvedConstructorOrFactoryMethod != null) {
			if (mbd.constructorArgumentsResolved) {
				return autowireConstructor(beanName, mbd, null, args);
			}
			else {
			//最常见的生成实例的方法,使用cglib
				return instantiateBean(beanName, mbd);
			}
		}
		//使用构造函数实例化
		// Need to determine the constructor...
		Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
		//使用构造函数完成实例化
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// No special handling: simply use no-arg constructor.
		//使用默认的构造函数实例化
		return instantiateBean(beanName, mbd);
	}

下面我们看一个如何使用构造函数完成实例化


	protected BeanWrapper autowireConstructor(
			String beanName, RootBeanDefinition mbd, Constructor[] chosenCtors, Object[] explicitArgs) {
		//
		BeanWrapperImpl bw = new BeanWrapperImpl();
		this.beanFactory.initBeanWrapper(bw);

		Constructor constructorToUse = null;
		Object[] argsToUse = null;

		if (explicitArgs != null) {
			argsToUse = explicitArgs;
		}
		else {
			constructorToUse = (Constructor) mbd.resolvedConstructorOrFactoryMethod;
			if (constructorToUse != null) {
				// Found a cached constructor...
				argsToUse = mbd.resolvedConstructorArguments;
				if (argsToUse == null) {
					Class[] paramTypes = constructorToUse.getParameterTypes();
					Object[] argsToResolve = mbd.preparedConstructorArguments;
					TypeConverter converter = (this.typeConverter != null ? this.typeConverter : bw);
					BeanDefinitionValueResolver valueResolver =
							new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
					argsToUse = new Object[argsToResolve.length];
					for (int i = 0; i < argsToResolve.length; i++) {
						Object argValue = argsToResolve[i];
						MethodParameter methodParam = new MethodParameter(constructorToUse, i);
						if (JdkVersion.isAtLeastJava15()) {
							GenericTypeResolver.resolveParameterType(methodParam, constructorToUse.getDeclaringClass());
						}
						if (argValue instanceof AutowiredArgumentMarker) {
							argValue = resolveAutowiredArgument(methodParam, beanName, null, converter);
						}
						else if (argValue instanceof BeanMetadataElement) {
							argValue = valueResolver.resolveValueIfNecessary("constructor argument", argValue);
						}
						argsToUse[i] = converter.convertIfNecessary(argValue, paramTypes[i], methodParam);
					}
				}
			}
		}

		if (constructorToUse == null) {
			// Need to resolve the constructor.
			boolean autowiring = (chosenCtors != null ||
					mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
			ConstructorArgumentValues resolvedValues = null;

			int minNrOfArgs = 0;
			if (explicitArgs != null) {
				minNrOfArgs = explicitArgs.length;
			}
			else {
				ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
				resolvedValues = new ConstructorArgumentValues();
				minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
			}

			// Take specified constructors, if any.
			Constructor[] candidates =
					(chosenCtors != null ? chosenCtors : mbd.getBeanClass().getDeclaredConstructors());
			AutowireUtils.sortConstructors(candidates);
			int minTypeDiffWeight = Integer.MAX_VALUE;

			for (int i = 0; i < candidates.length; i++) {
				Constructor candidate = candidates[i];
				Class[] paramTypes = candidate.getParameterTypes();

				if (constructorToUse != null && argsToUse.length > paramTypes.length) {
					// Already found greedy constructor that can be satisfied ->
					// do not look any further, there are only less greedy constructors left.
					break;
				}
				if (paramTypes.length < minNrOfArgs) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							minNrOfArgs + " constructor arguments specified but no matching constructor found in bean '" +
							beanName + "' " +
							"(hint: specify index and/or type arguments for simple parameters to avoid type ambiguities)");
				}

				ArgumentsHolder args = null;
				List causes = null;

				if (resolvedValues != null) {
					// Try to resolve arguments for current constructor.
					try {
						args = createArgumentArray(
								beanName, mbd, resolvedValues, bw, paramTypes, candidate, autowiring);
					}
					catch (UnsatisfiedDependencyException ex) {
						if (this.beanFactory.logger.isTraceEnabled()) {
							this.beanFactory.logger.trace(
									"Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
						}
						if (i == candidates.length - 1 && constructorToUse == null) {
							if (causes != null) {
								for (Iterator it = causes.iterator(); it.hasNext();) {
									this.beanFactory.onSuppressedException((Exception) it.next());
								}
							}
							throw ex;
						}
						else {
							// Swallow and try next constructor.
							if (causes == null) {
								causes = new LinkedList();
							}
							causes.add(ex);
							continue;
						}
					}
				}

				else {
					// Explicit arguments given -> arguments length must match exactly.
					if (paramTypes.length != explicitArgs.length) {
						continue;
					}
					args = new ArgumentsHolder(explicitArgs);
				}

				int typeDiffWeight = args.getTypeDifferenceWeight(paramTypes);
				// Choose this constructor if it represents the closest match.
				if (typeDiffWeight < minTypeDiffWeight) {
					constructorToUse = candidate;
					argsToUse = args.arguments;
					minTypeDiffWeight = typeDiffWeight;
				}
			}

			if (constructorToUse == null) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Could not resolve matching constructor");
			}

			if (explicitArgs == null) {
				mbd.resolvedConstructorOrFactoryMethod = constructorToUse;
			}
		}

		try {
			Object beanInstance = this.instantiationStrategy.instantiate(
					mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
			bw.setWrappedInstance(beanInstance);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}

	


下面是比较常用的,使用createBeanInstance来创建,cglib代理的对象

protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
//使用cglib来进行实例化
Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}


	public Object instantiate(
			RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {

		// Don't override the class with CGLIB if no overrides.
		if (beanDefinition.getMethodOverrides().isEmpty()) {
			Constructor constructorToUse = (Constructor) beanDefinition.resolvedConstructorOrFactoryMethod;
			if (constructorToUse == null) {
				Class clazz = beanDefinition.getBeanClass();
				if (clazz.isInterface()) {
					throw new BeanInstantiationException(clazz, "Specified class is an interface");
				}
				try {
					constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
					beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
				}
				catch (Exception ex) {
					throw new BeanInstantiationException(clazz, "No default constructor found", ex);
				}
			}
			return BeanUtils.instantiateClass(constructorToUse, null);
		}
		else {
			// Must generate CGLIB subclass.
			return instantiateWithMethodInjection(beanDefinition, beanName, owner);
		}
	}
	


没有找到怎么用cglib创建.

BeanUtils.instantiateClass(constructorToUse, null)是用java的反射实现的


======================================================================================

2.依赖注入的的准备工作:处理对象,设置依赖关系

现在我们已经分析完了实例化的整个过程,接下来就是处理这些对象,设置好依赖关系完成整个依赖注入的过程.


protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {
		//获取property值,
		PropertyValues pvs = mbd.getPropertyValues();

		if (bw == null) {
			if (!pvs.isEmpty()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			else {
				// Skip property population phase for null instance.
				return;
			}
		}

		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
		// state of the bean before properties are set. This can be used, for example,
		// to support styles of field injection.
		//调用后置处理器
		boolean continueWithPropertyPopulation = true;
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
				BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
				if (beanProcessor instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}
		//判定是否继续处理property
		if (!continueWithPropertyPopulation) {
			return;
		}
		//进行依赖注入的过程,先处理autowire,有ByName和ByType两种类型
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			//通过name自动装填
			// Add property values based on autowire by name if applicable.
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			//通过type自动装填
			// Add property values based on autowire by type if applicable.
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}

			pvs = newPvs;
		}
		//检查容器是否持有用于处理单态模式Bean关闭时的后置处理器
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		//检查是否有继承的类,即是否有依赖
		boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

		if (hasInstAwareBpps || needsDepCheck) {
		 //从实例对象中提取属性描述符
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw);
			if (hasInstAwareBpps) {
				for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext(); ) {
					BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
					if (beanProcessor instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor;
						//使用后置处理器处理
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvs == null) {
							return;
						}
					}
				}
			}
			if (needsDepCheck) {
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}
		//对具体参数进行注入
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
	

我们继续分析生成对象后, Spring IoC 容器是如何将 Bean 的属性依赖关系注入 Bean 实例对象中并设置好的,属性依赖注入的代码如下:


	protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
		if (pvs == null || pvs.isEmpty()) {
			return;
		}
		//封装属性值
		MutablePropertyValues mpvs = null;
		//所有属性对象的list
		List original = null;

		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 new BeanCreationException(
							mbd.getResourceDescription(), beanName, "Error setting property values", ex);
				}
			}
			original = mpvs.getPropertyValueList();
		}
		else {
			original = Arrays.asList(pvs.getPropertyValues());
		}
		//是否设置类型转换器了,没设置的话使用BeanWrapper
		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}
		//Bean属性值解析器
		BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
		//为解析值创建一个副本,
		// Create a deep copy, resolving any references for values.
		List deepCopy = new ArrayList(original.size());
		boolean resolveNecessary = false;
		for (Iterator it = original.iterator(); it.hasNext();) {
			PropertyValue pv = (PropertyValue) it.next();
			//不需要转化是属性值
			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 = !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
				if (convertible) {
				//如果可以转换,使用用户自己的转换器
					convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
				}
				// Possibly store converted value in merged bean definition,
				// in order to avoid re-conversion for every created bean instance.
				//可以转换,储存转换的值,避免每次都转换
				if (resolvedValue == originalValue) {
					if (convertible) {
						pv.setConvertedValue(convertedValue);
					}
					deepCopy.add(pv);
				}//是string类型的值,并且可以转换
				else if (originalValue instanceof TypedStringValue && convertible) {
					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 {
		//进行依赖注入,在BeanWrapper中实现
			bw.setPropertyValues(new MutablePropertyValues(deepCopy));
		}
		catch (BeansException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Error setting property values", ex);
		}
	}

	
下面是转换属性值的过程.如将引用转化为实例对象


	//检查value的类型,如果是对象的引用转化为对象的实例
		public Object resolveValueIfNecessary(Object argName, Object value) {
		// We must check each value to see whether it requires a runtime reference
		// to another bean to be resolved.
		//将对象的引用转化为实例
		if (value instanceof RuntimeBeanReference) {
			RuntimeBeanReference ref = (RuntimeBeanReference) value;
			return resolveReference(argName, ref);
		}//属性值是引用容器中另一个Bean名称
		else if (value instanceof RuntimeBeanNameReference) {
			String ref = ((RuntimeBeanNameReference) value).getBeanName();
			if (!this.beanFactory.containsBean(ref)) {
				throw new BeanDefinitionStoreException(
						"Invalid bean name '" + ref + "' in bean reference for " + argName);
			}
			return ref;
		}//属性值是Bean类型的解析,主要是Bean中的内部类
		else if (value instanceof BeanDefinitionHolder) {
			// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
			BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
			return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
		}
		//
		else if (value instanceof BeanDefinition) {
			// Resolve plain BeanDefinition, without contained name: use dummy name.
			BeanDefinition bd = (BeanDefinition) value;
			return resolveInnerBean(argName, "(inner bean)", bd);
		}//解析List,封装成Set<resolveValueIfNecessary>
		else if (value instanceof ManagedList) {
			// May need to resolve contained runtime references.
			return resolveManagedList(argName, (List) value);
		}//Set
		else if (value instanceof ManagedSet) {
			// May need to resolve contained runtime references.
			return resolveManagedSet(argName, (Set) value);
		}//Map
		else if (value instanceof ManagedMap) {
			// May need to resolve contained runtime references.
			return resolveManagedMap(argName, (Map) value);
		}// //解析props类型的属性值,props其实就是key和value均为字符串的map  
		else if (value instanceof ManagedProperties) {
			Properties original = (Properties) value;
			Properties copy = new Properties();
			for (Iterator it = original.entrySet().iterator(); it.hasNext();) {
				Map.Entry propEntry = (Map.Entry) it.next();
				Object propKey = propEntry.getKey();
				Object propValue = propEntry.getValue();
				if (propKey instanceof TypedStringValue) {
					propKey = ((TypedStringValue) propKey).getValue();
				}
				if (propValue instanceof TypedStringValue) {
					propValue = ((TypedStringValue) propValue).getValue();
				}
				copy.put(propKey, propValue);
			}
			return copy;
		}//如果值是String类型的,
		else if (value instanceof TypedStringValue) {
			// Convert value to target type here.
			TypedStringValue typedStringValue = (TypedStringValue) value;
			try {
				Class resolvedTargetType = resolveTargetType(typedStringValue);
				if (resolvedTargetType != null) {
					return this.typeConverter.convertIfNecessary(typedStringValue.getValue(), resolvedTargetType);
				}
				else {
					// No target type specified - no conversion necessary...
					return typedStringValue.getValue();
				}
			}
			catch (Throwable ex) {
				// Improve the message by showing the context.
				throw new BeanCreationException(
						this.beanDefinition.getResourceDescription(), this.beanName,
						"Error converting typed String value for " + argName, ex);
			}
		}
		else {
			// No need to resolve value...
			return value;
		}
	}


将对象引用转化为对象实例的过程如下


	
	
	//将一个引用转化为一个实例
		private Object resolveReference(Object argName, RuntimeBeanReference ref) {
		try {
		//如果这个实例在父BeanFactory中的话,在父类中获取
		//递归调用加载Bean的过程
			if (ref.isToParent()) {
				if (this.beanFactory.getParentBeanFactory() == null) {
					throw new BeanCreationException(
							this.beanDefinition.getResourceDescription(), this.beanName,
							"Can't resolve reference to bean '" + ref.getBeanName() +
							"' in parent factory: no parent factory available");
				}
				return this.beanFactory.getParentBeanFactory().getBean(ref.getBeanName());
			}
			else {
				Object bean = this.beanFactory.getBean(ref.getBeanName());
				this.beanFactory.registerDependentBean(ref.getBeanName(), this.beanName);
				return bean;
			}
		}
		catch (BeansException ex) {
			throw new BeanCreationException(
					this.beanDefinition.getResourceDescription(), this.beanName,
					"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
		}
	}



3.依赖注入开始

完成这个解析过程后,已经为依赖注入做好了准备,

	//实现属性依赖注入功能
	public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)
			throws BeansException {

		List propertyAccessExceptions = null;
		List propertyValues = (pvs instanceof MutablePropertyValues ?
				((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
		//
		for (Iterator it = propertyValues.iterator(); it.hasNext();) {
			PropertyValue pv = (PropertyValue) it.next();
			try {
				// This method may throw any BeansException, which won't be caught
				// here, if there is a critical failure such as no matching field.
				// We can attempt to deal only with less serious exceptions.
				//依赖注入每个属性
				setPropertyValue(pv);
			}
			catch (NotWritablePropertyException ex) {
				if (!ignoreUnknown) {
					throw ex;
				}
				// Otherwise, just ignore it and continue...
			}
			catch (NullValueInNestedPathException ex) {
				if (!ignoreInvalid) {
					throw ex;
				}
				// Otherwise, just ignore it and continue...
			}
			catch (PropertyAccessException ex) {
				if (propertyAccessExceptions == null) {
					propertyAccessExceptions = new LinkedList();
				}
				propertyAccessExceptions.add(ex);
			}
		}

		// If we encountered individual exceptions, throw the composite exception.
		if (propertyAccessExceptions != null) {
			PropertyAccessException[] paeArray = (PropertyAccessException[])
					propertyAccessExceptions.toArray(new PropertyAccessException[propertyAccessExceptions.size()]);
			throw new PropertyBatchUpdateException(paeArray);
		}
	}

继续调用下面的方法


//在BeanWrapperImpl中实现了这个方法
public void setPropertyValue(PropertyValue pv) throws BeansException {
		PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;
		if (tokens == null) {
			String propertyName = pv.getName();
			BeanWrapperImpl nestedBw = null;
			try {
				nestedBw = getBeanWrapperForPropertyPath(propertyName);
			}
			catch (NotReadablePropertyException ex) {
				throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
						"Nested property in path '" + propertyName + "' does not exist", ex);
			}
			tokens = getPropertyNameTokens(getFinalPath(nestedBw, propertyName));
			if (nestedBw == this) {
				pv.getOriginalPropertyValue().resolvedTokens = tokens;
			}
			nestedBw.setPropertyValue(tokens, pv);
		}
		else {
			setPropertyValue(tokens, pv);
		}
	}

实现属性依赖注入

//依赖注解的具体实现
	private void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
		//PropertyTokenHolder主要保存属性的名称、路径,以及集合的size等信息
		String propertyName = tokens.canonicalName;
		String actualName = tokens.actualName;
		 //keys是用来保存集合类型属性的size 
		if (tokens.keys != null) {
			// Apply indexes and map keys: fetch value for all keys but the last one.
			//复制token
			PropertyTokenHolder getterTokens = new PropertyTokenHolder();
			getterTokens.canonicalName = tokens.canonicalName;
			getterTokens.actualName = tokens.actualName;
			getterTokens.keys = new String[tokens.keys.length - 1];
			System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1);
			Object propValue = null;
			try {
			//获取属性值,该方法内部使用JDK的内省( Introspector)机制,调用属性//的getter(readerMethod)方法,获取属性的值  
				propValue = getPropertyValue(getterTokens);
			}
			catch (NotReadablePropertyException ex) {
				throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
						"Cannot access indexed value in property referenced " +
						"in indexed property path '" + propertyName + "'", ex);
			}
			// Set value for last key.
			获取集合类型属性的长度 
			String key = tokens.keys[tokens.keys.length - 1];
			if (propValue == null) {
				throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName,
						"Cannot access indexed value in property referenced " +
						"in indexed property path '" + propertyName + "': returned null");
			}//数组处理
			else if (propValue.getClass().isArray()) {
			//数组属性
				Class requiredType = propValue.getClass().getComponentType();
				//数组长度
				int arrayIndex = Integer.parseInt(key);
				Object oldValue = null;
				try {
					if (isExtractOldValueForEditor()) {
						oldValue = Array.get(propValue, arrayIndex);
					}
					Object convertedValue = this.typeConverterDelegate.convertIfNecessary(
							propertyName, oldValue, pv.getValue(), requiredType);
					Array.set(propValue, Integer.parseInt(key), convertedValue);
				}
				catch (IllegalArgumentException ex) {
					PropertyChangeEvent pce =
							new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
					throw new TypeMismatchException(pce, requiredType, ex);
				}
				catch (IndexOutOfBoundsException ex) {
					throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
							"Invalid array index in property path '" + propertyName + "'", ex);
				}
			}//注入list型的
			else if (propValue instanceof List) {
			
				PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
				//List里面的元素类型
				Class requiredType = null;
				if (JdkVersion.isAtLeastJava15()) {
					requiredType = GenericCollectionTypeResolver.getCollectionReturnType(
							pd.getReadMethod(), tokens.keys.length);
				}
				List list = (List) propValue;
				int index = Integer.parseInt(key);
				Object oldValue = null;
				if (isExtractOldValueForEditor() && index < list.size()) {
					oldValue = list.get(index);
				}
				try {
					Object convertedValue = this.typeConverterDelegate.convertIfNecessary(
							propertyName, oldValue, pv.getValue(), requiredType);
					if (index < list.size()) {
						list.set(index, convertedValue);
					}
					else if (index >= list.size()) {
						for (int i = list.size(); i < index; i++) {
							try {
								list.add(null);
							}
							catch (NullPointerException ex) {
								throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
										"Cannot set element with index " + index + " in List of size " +
										list.size() + ", accessed using property path '" + propertyName +
										"': List does not support filling up gaps with null elements");
							}
						}
						list.add(convertedValue);
					}
				}
				catch (IllegalArgumentException ex) {
					PropertyChangeEvent pce =
							new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
					throw new TypeMismatchException(pce, requiredType, ex);
				}
			}
			else if (propValue instanceof Map) {//map类型的
				PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
				Class mapKeyType = null;
				Class mapValueType = null;
				if (JdkVersion.isAtLeastJava15()) {
					mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(
							pd.getReadMethod(), tokens.keys.length);
					mapValueType = GenericCollectionTypeResolver.getMapValueReturnType(
							pd.getReadMethod(), tokens.keys.length);
				}
				Map map = (Map) propValue;
				Object convertedMapKey = null;
				Object convertedMapValue = null;
				try {
					// IMPORTANT: Do not pass full property name in here - property editors
					// must not kick in for map keys but rather only for map values.
					convertedMapKey = this.typeConverterDelegate.convertIfNecessary(key, mapKeyType);
				}
				catch (IllegalArgumentException ex) {
					PropertyChangeEvent pce =
							new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, null, pv.getValue());
					throw new TypeMismatchException(pce, mapKeyType, ex);
				}
				Object oldValue = null;
				if (isExtractOldValueForEditor()) {
					oldValue = map.get(convertedMapKey);
				}
				try {
					// Pass full property name and old value in here, since we want full
					// conversion ability for map values.
					convertedMapValue = this.typeConverterDelegate.convertIfNecessary(
							propertyName, oldValue, pv.getValue(), mapValueType, null,
							new MethodParameter(pd.getReadMethod(), -1, tokens.keys.length + 1));
				}
				catch (IllegalArgumentException ex) {
					PropertyChangeEvent pce =
							new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
					throw new TypeMismatchException(pce, mapValueType, ex);
				}
				map.put(convertedMapKey, convertedMapValue);
			}
			else {
				throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
						"Property referenced in indexed property path '" + propertyName +
						"' is neither an array nor a List nor a Map; returned value was [" + pv.getValue() + "]");
			}
		}

		else {//
			PropertyDescriptor pd = pv.resolvedDescriptor;
			if (pd == null || !pd.getWriteMethod().getDeclaringClass().isInstance(this.object)) {
				pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
				if (pd == null || pd.getWriteMethod() == null) {
					PropertyMatches matches = PropertyMatches.forProperty(propertyName, getRootClass());
					throw new NotWritablePropertyException(
							getRootClass(), this.nestedPath + propertyName,
							matches.buildErrorMessage(), matches.getPossibleMatches());
				}
				pv.getOriginalPropertyValue().resolvedDescriptor = pd;
			}

			Object oldValue = null;
			try {
				Object originalValue = pv.getValue();
				Object valueToApply = originalValue;
				if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
					if (pv.isConverted()) {
						valueToApply = pv.getConvertedValue();
					}
					else {
						if (isExtractOldValueForEditor() && pd.getReadMethod() != null) {
							Method readMethod = pd.getReadMethod();
							if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
								readMethod.setAccessible(true);
							}
							try {
								oldValue = readMethod.invoke(this.object, new Object[0]);
							}
							catch (Exception ex) {
								if (logger.isDebugEnabled()) {
									logger.debug("Could not read previous value of property '" +
											this.nestedPath + propertyName + "'", ex);
								}
							}
						}
						valueToApply = this.typeConverterDelegate.convertIfNecessary(oldValue, originalValue, pd);
					}
					pv.getOriginalPropertyValue().conversionNecessary = Boolean.valueOf(valueToApply != originalValue);
				}
				Method writeMethod = pd.getWriteMethod();
				if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
					writeMethod.setAccessible(true);
				}
				writeMethod.invoke(this.object, new Object[] {valueToApply});
			}
			catch (InvocationTargetException ex) {
				PropertyChangeEvent propertyChangeEvent =
						new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
				if (ex.getTargetException() instanceof ClassCastException) {
					throw new TypeMismatchException(propertyChangeEvent, pd.getPropertyType(), ex.getTargetException());
				}
				else {
					throw new MethodInvocationException(propertyChangeEvent, ex.getTargetException());
				}
			}
			catch (IllegalArgumentException ex) {
				PropertyChangeEvent pce =
						new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
				throw new TypeMismatchException(pce, pd.getPropertyType(), ex);
			}
			catch (IllegalAccessException ex) {
				PropertyChangeEvent pce =
						new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
				throw new MethodInvocationException(pce, ex);
			}
		}
	}

	
	

通过对上面注入依赖代码的分析,我们已经明白了Spring IoC容器是如何将属性的值注入到Bean实例对象中去的:

(1).对于集合类型的属性,将其属性值解析为目标类型的集合后直接赋值给属性。

(2).对于非集合类型的属性,大量使用了JDK的反射和内省机制,通过属性的getter方法(reader method)获取指定属性注入以前的值,同时调用属性的setter方法(writer method)为属性设置注入后的值。看到这里相信很多人都明白了Spring的setter注入原理。

至此Spring IoC容器对Bean定义资源文件的定位,载入、解析和依赖注入已经全部分析完毕,现在Spring IoC容器中管理了一系列靠依赖关系联系起来的Bean,应用程序不需要自己手动创建所需的对象,Spring IoC容器会在我们使用的时候自动为我们创建,并且为我们注入好相关的依赖,这就是Spring核心功能的控制反转和依赖注入的相关功能。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值