Spring框架进阶Spring V3.0 DI源码分析流程

Posted 烟锁迷城

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring框架进阶Spring V3.0 DI源码分析流程相关的知识,希望对你有一定的参考价值。

目录

1、总体分析

1.1、依赖注入情形

1.2、实例化

1.3、存储相关信息

1.4、关键方法

2、源码分析

3、流程总结

3.1、实例化

3.2、依赖注入


1、总体分析

1.1、依赖注入情形

在Spring框架中,实现getBean方法的类是AbstractBeanFactory。

在IOC完成对应的配置信息加载之后,IOC就可以开始对Bean进行管理了。但此时的Bean还没有完成依赖注入,只有经过依赖注入之后,才能继续使用。

Bean的依赖注入过程发生在两种情形下:

  • 在getBean方法被首次调用的时候,触发依赖注入
  • 在非懒加载的情况下,容器解析Bean时进行预实例化

1.2、实例化

在符合AOP代理条件的情形下,实例化的是对象的代理类,反之则实例化原生对象。

1.3、存储相关信息

将实例化的类封装到BeanWrapper之中,统一访问入口,拓展功能,缓存相关信息

1.4、关键方法

instantiateBean:实例化

populateBean:依赖注入

2、源码分析

ApplicationContext依旧是起始入口,但这次我们无法在这个类中找到需要的getBean方法,不过不要紧,还记得之前提到的ApplicationContext和DefaultListableBeanFactory都继承的类BeanFactory吗?getBean就在这里,而它的具体实现在抽象类AbstractBeanFactory之中

ApplicationContext调用AbstractBeanFactorygetBean方法,内部是doGetBean方法,即真正的执行方法。

Object sharedInstance = getSingleton(beanName),从三级缓存中获取到Bean

bean = getObjectForBeanInstance(sharedInstance, name, beanName, null),如果缓存中的Bean不为空,且Object[]数组为空(必定为空),以此方法获取给定的实例,会尝试从缓存factoryBeanObjectCache 之中获取

private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16)

如果缓存中没有,就使用Bean工厂尝试创建,成功后放入缓存factoryBeanObjectCach之中。

createBean(beanName, mbd, args),创建Bean的方法

public Object getBean(String name) throws BeansException 
	//doGetBean才是真正向IoC容器获取被管理Bean的过程
	return doGetBean(name, null, null, false);

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
		@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException 

	//根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖
	//如果指定的是别名,将别名转换为规范的Bean名称
	final String beanName = transformedBeanName(name);
	Object bean;

	// Eagerly check singleton cache for manually registered singletons.
	//先从缓存中取是否已经有被创建过的单态类型的Bean
	//对于单例模式的Bean整个IOC容器中只创建一次,不需要重复创建
	Object sharedInstance = getSingleton(beanName);
	//IOC容器创建单例模式Bean实例对象
	if (sharedInstance != null && args == null) 
		if (logger.isDebugEnabled()) 
			//如果指定名称的Bean在容器中已有单例模式的Bean被创建
			//直接返回已经创建的Bean
			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的实例对象,主要是完成FactoryBean的相关处理
		//注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是
		//创建创建对象的工厂Bean,两者之间有区别
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	

	else 
		// Fail if we're already creating this bean instance:
		// We're assumably within a circular reference.
		//缓存没有正在创建的单例模式Bean
		//缓存中已经有已经创建的原型模式Bean
		//但是由于循环引用的问题导致实例化对象失败
		if (isPrototypeCurrentlyInCreation(beanName)) 
			throw new BeanCurrentlyInCreationException(beanName);
		

		// Check if bean definition exists in this factory.
		//对IOC容器中是否存在指定名称的BeanDefinition进行检查,首先检查是否
		//能在当前的BeanFactory中获取的所需要的Bean,如果不能则委托当前容器
		//的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找
		BeanFactory parentBeanFactory = getParentBeanFactory();
		//当前容器的父级容器存在,且当前容器中不存在指定名称的Bean
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) 
			// Not found -> check parent.
			//解析指定Bean名称的原始名称
			String nameToLookup = originalBeanName(name);
			if (parentBeanFactory instanceof AbstractBeanFactory) 
				return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
						nameToLookup, requiredType, args, typeCheckOnly);
			
			else if (args != null) 
				// Delegation to parent with explicit args.
				//委派父级容器根据指定名称和显式的参数查找
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			
			else 
				// No args -> delegate to standard getBean method.
				//委派父级容器根据指定名称和类型查找
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			
		

		//创建的Bean是否需要进行类型验证,一般不需要
		if (!typeCheckOnly) 
			//向容器标记指定的Bean已经被创建
			markBeanAsCreated(beanName);
		

		try 
			//根据指定Bean名称获取其父级的Bean定义
			//主要解决Bean继承时子类合并父类公共属性问题
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);

			// Guarantee initialization of beans that the current bean depends on.
			//获取当前Bean所有依赖Bean的名称
			String[] dependsOn = mbd.getDependsOn();
			//如果当前Bean有依赖Bean
			if (dependsOn != null) 
				for (String dep : dependsOn) 
					if (isDependent(beanName, dep)) 
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					
					//递归调用getBean方法,获取当前Bean的依赖Bean
					registerDependentBean(dep, beanName);
					//把被依赖Bean注册给当前依赖的Bean
					getBean(dep);
				
			

			// Create bean instance.
			//创建单例模式Bean的实例对象
			if (mbd.isSingleton()) 
				//这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
				sharedInstance = getSingleton(beanName, () -> 
					try 
						//创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义
						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.
						//显式地从容器单例模式Bean缓存中清除实例对象
						destroySingleton(beanName);
						throw ex;
					
				);
				//获取给定Bean的实例对象
				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			

			//IOC容器创建原型模式Bean实例对象
			else if (mbd.isPrototype()) 
				// It's a prototype -> create a new instance.
				//原型模式(Prototype)是每次都会创建一个新的对象
				Object prototypeInstance = null;
				try 
					//回调beforePrototypeCreation方法,默认的功能是注册当前创建的原型对象
					beforePrototypeCreation(beanName);
					//创建指定Bean对象实例
					prototypeInstance = createBean(beanName, mbd, args);
				
				finally 
					//回调afterPrototypeCreation方法,默认的功能告诉IOC容器指定Bean的原型对象不再创建
					afterPrototypeCreation(beanName);
				
				//获取给定Bean的实例对象
				bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			

			//要创建的Bean既不是单例模式,也不是原型模式,则根据Bean定义资源中
			//配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中
			//比较常用,如:request、session、application等生命周期
			else 
				String scopeName = mbd.getScope();
				final Scope scope = this.scopes.get(scopeName);
				//Bean定义资源中没有配置生命周期范围,则Bean定义不合法
				if (scope == null) 
					throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
				
				try 
					//这里又使用了一个匿名内部类,获取一个指定生命周期范围的实例
					Object scopedInstance = scope.get(beanName, () -> 
						beforePrototypeCreation(beanName);
						try 
							return createBean(beanName, mbd, args);
						
						finally 
							afterPrototypeCreation(beanName);
						
					);
					//获取给定Bean的实例对象
					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);
				
			
		
		catch (BeansException ex) 
			cleanupAfterBeanCreationFailure(beanName);
			throw ex;
		
	

	// Check if required type matches the type of the actual bean instance.
	//对创建的Bean实例对象进行类型检查
	if (requiredType != null && !requiredType.isInstance(bean)) 
		try 
			T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
			if (convertedBean == null) 
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			
			return convertedBean;
		
		catch (TypeMismatchException ex) 
			if (logger.isDebugEnabled()) 
				logger.debug("Failed to convert bean '" + name + "' to required type '" +
						ClassUtils.getQualifiedName(requiredType) + "'", ex);
			
			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		
	
	return (T) bean;

createBean是创建Bean的方法,在这里执行真正的执行方法doCreateBean

resolveBeanClass方法确定是否可以由当前的类加载器进行加载,这涉及到双亲委派,如果这个类加载器无法获取到,就交给父类加载器进行加载,直至顶级类加载器,如果还是没有,就交给子类加载器去创建。

但首次执行,这里肯定没有,所以一定会去执行真正的创建方法,doGreateBean

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException 

	if (logger.isDebugEnabled()) 
		logger.debug("Creating instance of bean '" + beanName + "'");
	
	RootBeanDefinition mbdToUse = mbd;

	// Make sure bean class is actually resolved at this point, and
	// clone the bean definition in case of a dynamically resolved Class
	// which cannot be stored in the shared merged bean definition.
	//判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载
	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) 
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	

	// Prepare method overrides.
	//校验和准备Bean中的方法覆盖
	try 
		mbdToUse.prepareMethodOverrides();
	
	catch (BeanDefinitionValidationException ex) 
		throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
				beanName, "Validation of method overrides failed", ex);
	

	try 
		// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
		//如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建Bean的代理对象
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		if (bean != null) 
			return bean;
		
	
	catch (Throwable ex) 
		throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
				"BeanPostProcessor before instantiation of bean failed", ex);
	

	try 
		//创建Bean的入口
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isDebugEnabled()) 
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		
		return beanInstance;
	
	catch (BeanCreationException ex) 
		// A previously detected exception with proper bean creation context already...
		throw ex;
	
	catch (ImplicitlyAppearedSingletonException ex) 
		// An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...
		throw ex;
	
	catch (Throwable ex) 
		throw new BeanCreationException(
				mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
	

在doCreateBean方法里,准备好了用来封装的类BeanWrapper。

如果没有从缓存中获取到封装对象,就执行createBeanInstance创建方法,参数除了beanName,BeanDefinition之外,还有构造函数的参数,因为实例化时,使用的构造函数未必是无参。

用来保存BeanWrapper的缓存为factoryBeanInstanceCache

private final Map<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>(16);

protected Object  doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
		throws BeanCreationException 

	// Instantiate the bean.
	//封装被创建的Bean对象
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) 
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	
	if (instanceWrapper == null) 
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	
	final Object bean = instanceWrapper.getWrappedInstance();
	//获取实例化对象的类型
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) 
		mbd.resolvedTargetType = beanType;
	

	// Allow post-processors to modify the merged bean definition.
	//调用PostProcessor后置处理器
	synchronized (mbd.postProcessingLock) 
		if (!mbd.postProcessed) 
			try 
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			
			catch (Throwable ex) 
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Post-processing of merged bean definition failed", ex);
			
			mbd.postProcessed = true;
		
	

	// Eagerly cache singletons to be able to resolve circular references
	// even when triggered by lifecycle interfaces like BeanFactoryAware.
	//向容器中缓存单例模式的Bean对象,以防循环引用
	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, () -> getEarlyBeanReference(beanName, mbd, bean));
	

	// Initialize the bean instance.
	//Bean对象的初始化,依赖注入在此触发
	//这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean
	Object exposedObject = bean;
	try 
		//将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象
		populateBean(beanName, mbd, instanceWrapper);
		//初始化Bean对象
		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) 
		//获取指定名称的已注册的单例模式Bean对象
		Object earlySingletonReference = getSingleton(beanName, false);
		if (earlySingletonReference != null) 
			//根据名称获取的已注册的Bean和正在实例化的Bean是同一个
			if (exposedObject == bean) 
				//当前实例化的Bean初始化完成
				exposedObject = earlySingletonReference;
			
			//当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象
			else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) 
				String[] dependentBeans = getDependentBeans(beanName);
				Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
				//获取当前Bean所依赖的其他Bean
				for (String dependentBean : dependentBeans) 
					//对依赖Bean进行类型检查
					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.
	//注册完成依赖注入的Bean
	try 
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	
	catch (BeanDefinitionValidationException ex) 
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
	

	return exposedObject;

 实例化Bean方法,将执行对应的策略getInstantiationStrategy().instantiate(mbd, beanName, parent)

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) 
	try 
		Object beanInstance;
		final BeanFactory parent = this;
		//获取系统的安全管理接口,JDK标准的安全管理API
		if (System.getSecurityManager() != null) 
			//这里是一个匿名内置类,根据实例化策略创建实例对象
			beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
					getInstantiationStrategy().instantiate(mbd, beanName, parent),
					getAccessControlContext());
		
		else 
			//将实例化的对象封装起来
			beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
		
		BeanWrapper bw = new BeanWrapperImpl(beanInstance);
		initBeanWrapper(bw);
		return bw;
	
	catch (Throwable ex) 
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
	

 SimpleInstantiationStrategy类中,进入到对应策略之中,如果该类没有重写过方法,就不再执行CGLIB的实现方法。

接下来获取构造或工厂方法,如果此类为接口,不再执行构建,反之则构建需要的参数,最后执行BeanUtils.instantiateClass完成实例化。

如果有重写,则将执行CGLIB的类CglibSubclassingInstantiationStrategy策略,它继承了SimpleInstantiationStrategy,执行的方法是instantiateWithMethodInjection,这个方法调用了重写的instantiate方法,依旧执行BeanUtils.instantiateClass。

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) 
	// Don't override the class with CGLIB if no overrides.
	//如果Bean定义中没有方法覆盖,则就不需要CGLIB父类类的方法
	if (!bd.hasMethodOverrides()) 
		Constructor<?> constructorToUse;
		synchronized (bd.constructorArgumentLock) 
			//获取对象的构造方法或工厂方法
			constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
			//如果没有构造方法且没有工厂方法
			if (constructorToUse == null) 
				//使用JDK的反射机制,判断要实例化的Bean是否是接口
				final Class<?> clazz = bd.getBeanClass();
				if (clazz.isInterface()) 
					throw new BeanInstantiationException(clazz, "Specified class is an interface");
				
				try 
					if (System.getSecurityManager() != null) 
						//这里是一个匿名内置类,使用反射机制获取Bean的构造方法
						constructorToUse = AccessController.doPrivileged(
								(PrivilegedExceptionAction<Constructor<?>>) () -> clazz.getDeclaredConstructor());
					
					else 
						constructorToUse =	clazz.getDeclaredConstructor();
					
					bd.resolvedConstructorOrFactoryMethod = constructorToUse;
				
				catch (Throwable ex) 
					throw new BeanInstantiationException(clazz, "No default constructor found", ex);
				
			
		
		//使用BeanUtils实例化,通过反射机制调用”构造方法.newInstance(arg)”来进行实例化
		return BeanUtils.instantiateClass(constructorToUse);
	
	else 
		// Must generate CGLIB subclass.
		//使用CGLIB来实例化对象
		return instantiateWithMethodInjection(bd, beanName, owner);
	

KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ? KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args)

获取到构造的所属类,进行判断。

KotlinDelegate.instantiateClass(ctor, args):使用有参构造实现

ctor.newInstance(args):使用无参构造完成

对于newInstance方法而言,如果传入参数就是使用有参构造,但如果传入的数组为空或长度为0,实际调用的则是无参构造

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException 
	Assert.notNull(ctor, "Constructor must not be null");
	try 
		ReflectionUtils.makeAccessible(ctor);
		return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
				KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
	
	catch (InstantiationException ex) 
		throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
	
	catch (IllegalAccessException ex) 
		throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
	
	catch (IllegalArgumentException ex) 
		throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
	
	catch (InvocationTargetException ex) 
		throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
	

接下来继续看populateBean方法,在这个方法中,将beanName,BeanDefinition,BeanWrapper作为条件找到需要复制的属性并封装在PropertyValues集合之中

PropertyValues内的属性PropertyValue列表,每一个PropertyValue都保存着需要赋值的类Bean,需要调用的方法和赋予的数值

真正要执行的方法,其实是在处置之后得到数值的PropertyValues不为空时执行的方法

applyPropertyValues

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) 
	if (bw == null) 
		if (mbd.hasPropertyValues()) 
			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 (BeanPostProcessor bp : getBeanPostProcessors()) 
			if (bp instanceof InstantiationAwareBeanPostProcessor) 
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) 
					continueWithPropertyPopulation = false;
					break;
				
			
		
	

	if (!continueWithPropertyPopulation) 
		return;
	
	//获取容器在解析Bean定义资源时为BeanDefiniton中设置的属性值
	PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

	//对依赖注入处理,首先处理autowiring自动装配的依赖注入
	if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
			mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) 
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

		// Add property values based on autowire by name if applicable.
		//根据Bean名称进行autowiring自动装配处理
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) 
			autowireByName(beanName, mbd, bw, newPvs);
		

		// Add property values based on autowire by type if applicable.
		//根据Bean类型进行autowiring自动装配处理
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) 
			autowireByType(beanName, mbd, bw, newPvs);
		

		pvs = newPvs;
	

	//对非autowiring的属性进行依赖注入处理

	boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
	boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

	if (hasInstAwareBpps || needsDepCheck) 
		if (pvs == null) 
			pvs = mbd.getPropertyValues();
		
		PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		if (hasInstAwareBpps) 
			for (BeanPostProcessor bp : getBeanPostProcessors()) 
				if (bp instanceof InstantiationAwareBeanPostProcessor) 
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvs == null) 
						return;
					
				
			
		
		if (needsDepCheck) 
			checkDependencies(beanName, mbd, filteredPds, pvs);
		
	

	if (pvs != null) 
		//对属性进行注入
		applyPropertyValues(beanName, mbd, bw, pvs);
	

 applyPropertyValues方法,继续创造注入,处理数据,最终要执行的方法,是setPropertyValues

bw.setPropertyValues(new MutablePropertyValues(deepCopy))

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) 
	if (pvs.isEmpty()) 
		return;
	

	//封装属性值
	MutablePropertyValues mpvs = null;
	List<PropertyValue> original;

	if (System.getSecurityManager() != null) 
		if (bw instanceof BeanWrapperImpl) 
			//设置安全上下文,JDK安全机制
			((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
		
	

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

	//获取用户自定义的类型转换
	TypeConverter converter = getCustomTypeConverter();
	if (converter == null) 
		converter = bw;
	
	//创建一个Bean定义属性值解析器,将Bean定义中的属性值解析为Bean实例对象的实际值
	BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

	// Create a deep copy, resolving any references for values.

	//为属性的解析值创建一个拷贝,将拷贝的数据注入到实例对象中
	List<PropertyValue> 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();
			//转换属性值,例如将引用转换为IOC容器中实例化对象引用
			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);
			
			// 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);
			
			//属性是可转换的,且属性原始值是字符串类型,且属性的原始类型值不是
			//动态生成的字符串,且属性的原始值不是集合或者数组类型
			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);
	

 setPropertyValues方法,使用访问者模式,给数据结构和数据操作解耦

继续查看重写方法,可以看到这里有一个循环,因为依赖注入的数据时一次性批量处理的,全部在一个容器PropertyValues中

循环内部,setPropertyValue方法继续注入

public void setPropertyValues(PropertyValues pvs) throws BeansException 
	setPropertyValues(pvs, false, false);

public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)
		throws BeansException 

	List<PropertyAccessException> propertyAccessExceptions = null;
	List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?
			((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
	for (PropertyValue pv : propertyValues) 
		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 =
				propertyAccessExceptions.toArray(new PropertyAccessException[propertyAccessExceptions.size()]);
		throw new PropertyBatchUpdateException(paeArray);
	

 以tokens是否为空做为判断依据,继续执行方法,但可以看到,其实这两个方法将走入一个判断中

public void setPropertyValue(PropertyValue pv) throws BeansException 
	PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;
	if (tokens == null) 
		String propertyName = pv.getName();
		AbstractNestablePropertyAccessor nestedPa;
		try 
			nestedPa = getPropertyAccessorForPropertyPath(propertyName);
		
		catch (NotReadablePropertyException ex) 
			throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
					"Nested property in path '" + propertyName + "' does not exist", ex);
		
		tokens = getPropertyNameTokens(getFinalPath(nestedPa, propertyName));
		if (nestedPa == this) 
			pv.getOriginalPropertyValue().resolvedTokens = tokens;
		
		nestedPa.setPropertyValue(tokens, pv);
	
	else 
		setPropertyValue(tokens, pv);
	

 跳转至processLocalProperty方法内,在这里继续执行ph.setValue(valueToApply)方法

protected void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException 
	if (tokens.keys != null) 
		processKeyedProperty(tokens, pv);
	
	else 
		processLocalProperty(tokens, pv);
	

private void processLocalProperty(PropertyTokenHolder tokens, PropertyValue pv) 
	PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);
	if (ph == null || !ph.isWritable()) 
		if (pv.isOptional()) 
			if (logger.isDebugEnabled()) 
				logger.debug("Ignoring optional value for property '" + tokens.actualName +
						"' - property not found on bean class [" + getRootClass().getName() + "]");
			
			return;
		
		else 
			throw createNotWritablePropertyException(tokens.canonicalName);
		
	

	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() && ph.isReadable()) 
					try 
						oldValue = ph.getValue();
					
					catch (Exception ex) 
						if (ex instanceof PrivilegedActionException) 
							ex = ((PrivilegedActionException) ex).getException();
						
						if (logger.isDebugEnabled()) 
							logger.debug("Could not read previous value of property '" +
									this.nestedPath + tokens.canonicalName + "'", ex);
						
					
				
				valueToApply = convertForProperty(
						tokens.canonicalName, oldValue, originalValue, ph.toTypeDescriptor());
			
			pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
		
		ph.setValue(valueToApply);
	
	catch (TypeMismatchException ex) 
		throw ex;
	
	catch (InvocationTargetException ex) 
		PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(
				getRootInstance(), this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());
		if (ex.getTargetException() instanceof ClassCastException) 
			throw new TypeMismatchException(propertyChangeEvent, ph.getPropertyType(), ex.getTargetException());
		
		else 
			Throwable cause = ex.getTargetException();
			if (cause instanceof UndeclaredThrowableException) 
				// May happen e.g. with Groovy-generated methods
				cause = cause.getCause();
			
			throw new MethodInvocationException(propertyChangeEvent, cause);
		
	
	catch (Exception ex) 
		PropertyChangeEvent pce = new PropertyChangeEvent(
				getRootInstance(), this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());
		throw new MethodInvocationException(pce, ex);
	

 最终,以反射调用方法进行注入,这里的writeMethod实际上是setter方法,也就是说,使用反射调用setter方法进行依赖注入

public void setValue(final @Nullable Object value) throws Exception 
	final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
			((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
			this.pd.getWriteMethod());
	if (System.getSecurityManager() != null) 
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> 
			ReflectionUtils.makeAccessible(writeMethod);
			return null;
		);
		try 
			AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
					writeMethod.invoke(getWrappedInstance(), value), acc);
		
		catch (PrivilegedActionException ex) 
			throw ex.getException();
		
	
	else 
		ReflectionUtils.makeAccessible(writeMethod);
		writeMethod.invoke(getWrappedInstance(), value);
	

3、流程总结

3.1、实例化

ApplicationContext:起始类,这个类中本身没有getBean方法,但是因为继承BeanFactory类,所以具有getBean方法,真正实现getBean方法的是AbstractBeanFactory

getBean:执行依赖注入的方法,获取到Bean

AbstractBeanFactory:

doGetBean:真正执行getBean的方法

AbstractBeanFactory:

createBean:创建Bean的方法

AbstractAutowireCapableBeanFactory:

doCreateBean:中以BeanWrapper进行封装

AbstractAutowireCapableBeanFactory:

createBeanInstance:创建Bean实例,与populateBean同在AbstractAutowireCapableBeanFactory

SimpleInstantiationStrategy:

instantiate:根据条件执行不同策略的代理方式,最后以反射实现实例化

3.2、依赖注入

populateBean:依赖注入,与createBeanInstance同在AbstractAutowireCapableBeanFactory,将beanName,BeanDefinition,BeanWrapper作为条件找到需要复制的属性并封装在PropertyValues集合之中

PropertyValues内的属性PropertyValue列表,每一个PropertyValue都保存着需要赋值的类Bean,需要调用的方法和赋予的数值

AbstractAutowireCapableBeanFactory:

applyPropertyValues:处理依照不同方式注入的数值之后,开始依赖注入。属于AbstractAutowireCapableBeanFactory

AbstractAutowireCapableBeanFactory:

setPropertyValues:使用访问者模式

AbstractPropertyAccessor:

setPropertyValue:PropertyValues将需要的依赖注入值保存到内部列表中,是一种迭代器加组合模式,之后循环执行此方法,进行注入依赖

AbstractNestablePropertyAccessor:

processLocalProperty:

AbstractNestablePropertyAccessor:

setValue:反射调用,将依赖注入

BeanWrapperImpl:

以上是关于Spring框架进阶Spring V3.0 DI源码分析流程的主要内容,如果未能解决你的问题,请参考以下文章

Spring框架进阶Spring V3.0 AOP源码分析流程

Spring框架进阶Spring V2.0 IOC与DI

Spring框架进阶Spring V2.0 IOC与DI

Spring框架进阶Spring V1.0

Spring框架进阶Spring V1.0

JAVA-Spring框架之IOC(DI)