栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring-IoC依赖注入

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring-IoC依赖注入

文章目录
  • 前言
  • 一、getBean()
  • 二、createBean()
    • 1.createBeanInstance()
    • 2.populateBean()
  • 总结

前言

前文对IoC容器的初始化过程进行了详细的分析,这个初始化过程完成的主要工作时IoC容器中建立了BeanDefinition数据映射。
但是并没有进行IoC容器对Bean依赖关系的注入,本篇文章就分析一下IoC容器时怎样对Bean的依赖关系进行注入的。

主要的方法调用顺序为getBean→doGetBean→createBean→doCreateBean→createBeanInstance→populateBean

一、getBean()

首先,注意到依赖注入的过程是用户第一次向IoC容器获取Bean时触发的,当然也有例外(BeanDefinition中设置lazy-init属性)。
就是BeanFactory接口的getBean()方法,我们从DefaultListableBeanFactory的基类AbstractBeanFactory里看看getBean()方法的实现。
部分代码如下所示。

	public Object getBean(String name) throws BeansException {
			return doGetBean(name, null, null, false);
	}
	
// 这里是实际取得Bean的地方,这也是出发依赖注入的地方!
	protected  T doGetBean(
			final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {
	    // 获取规范beanName
		final String beanName = transformedBeanName(name);
		Object bean;
     // 为手动注册的单例对象检查单例缓存
     // 先从缓存singletonObjects中取得Bean,处理那些已经被创建过的单例的Bean
     // private final Map singletonObjects = new ConcurrentHashMap(256);
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isDebugEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					// 返回未完全初始化的单例bean的快速缓存实例,这是循环引用的结果
				}
				else {
					// 返回单例bean的缓存实例
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		else {
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}
			//这里对Ioc容器中的BeanDefinition是否存在进行检查,检查是否能在当前的BeanFactory中取得需要的Bean,如果在当前的工厂中取不到,这道双亲BeanFactory中去取,如果当前的双亲工厂去不到,那就顺着双亲BeanFactory一直向上查找
			BeanFactory parentBeanFactory = getParentBeanFactory();
			// 省略...
			}
			try {
				// 这里根据Bean的名字取得BeanDefinition
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);
				// 获取当前Bean的所有依赖Bean,这样会出发getBean的递归调用,直到取到一个没有任何依赖的Bean为止
				String[] dependsOn = mbd.getDependsOn();
				// 省略...
				}
				//这里通过调用createBean方法创建Singleton Bean的实例,这里有一个回调函数getObject,会在getSingleton中调用ObjectFactory的createBean
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, new ObjectFactory() {
						@Override
						public Object getObject() throws BeansException {
							try {
								return createBean(beanName, mbd, args);
							}
							catch (BeansException ex) {
								destroySingleton(beanName);
								throw ex;
							}
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				//  省略....
		return (T) bean;
	}
 

重点来说,getBean是依赖注入的起点,之后会调用createBean,下面看看createBean代码。
在这个过程中,Bean对象会一局BeanDefinition定义的要求生成。在AbstractAutowireCapableBeanFactory中实现了createBean,createBean不仅生成了Bean,还对Bean初始化进行了处理,如实现了BeanDefinition中的init-method属性定义,Bean后置处理器等。

二、createBean()
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;
     // 这里判断需要创建的Bean是否可以实例化,这个类是否可以通过类加载器来载入
		Class resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}
		try {
       // 如果Bean配置了PostProcessor,name这里返回的是一个Proxy
			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);
		}
     // 这里开始创建Bean
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}

接着进入doCreateBean方法,看看里面是如何创建的。

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
			throws BeanCreationException {
     // 用来持有创建出来的Bean对象的
		BeanWrapper instanceWrapper = null;
		// 如果是Singleton就把缓存中同名的Bean对象清除
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//bean的实例化的地方
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
		Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
		mbd.resolvedTargetType = beanType;
		// 允许后置处理器修改合并的bean定义。 
		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;
			}
		}

		///快速缓存单例,以便能够解析循环引用,即使是由生命周期接口(如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");
			}
			//将得到的需要暴露的对象添加到singletonFactories中以解决循环依赖
			addSingletonFactory(beanName, new ObjectFactory() {
				@Override
				public Object getObject() throws BeansException {
					return getEarlyBeanReference(beanName, mbd, bean);
				}
			});
		}
        // 这里是对Bean的初始化,依赖注入就在这里发生,这个exposedObject在初始化处理完以后会返回作为依赖注入完成后的Bean
		Object exposedObject = bean;
		try {
			//属性填充
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
				//aop后置处理器
				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) {
				//aop代理情况下该对象经过了早期代理,exposedObject就是原先的bean,直接从二级缓存中获取代理后的对象
				//async代理情况下,exposedObject是代理之后的对象,两者不相等
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set actualDependentBeans = new linkedHashSet(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						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 " +
								"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}
		//将bean注册为一次性的
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}
		return exposedObject;
	}
 

doCreateBean里面我们主要看两个方法,一个是实例化Bean的方法:createBeanInstance(),一个是向Bean中注入属性的方法:populateBean()。

1.createBeanInstance()
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
		// 确保bean类在此时已实际解析。
		Class beanClass = resolveBeanClass(mbd, beanName);
		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}
		// 这里使用工厂方式进行实例化
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}
		// 当重新创建相同的bean时的快捷方式
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
			if (autowireNecessary) {
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				return instantiateBean(beanName, mbd);
			}
		}
		// 使用构造函数进行实例化
		Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == 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);
	}

当然,最常见的就是使用无参构造方法instantiateBean()进行实例化。

	protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		//使用默认的实例化策略对Bean进行实例化
		// 默认的实例化策略是CglibSubclassingInstantiationStrategy,就是使用CGLIB对Bean进行实例化,接着再看它的实现
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged(new PrivilegedAction() {
					@Override
					public Object run() {
						return 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);
		}
	}
 

instantiate()方法如下所示:

public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
		// 如果没有覆盖,不要用CGLIB覆盖类。
		if (bd.getMethodOverrides().isEmpty()) {
			// 这里取得指定的构造器或者生成对象的工厂方法来对Bean进行实例化
			Constructor constructorToUse;
			synchronized (bd.constructorArgumentLock) {
				constructorToUse = (Constructor) bd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse == null) {
					final Class clazz = bd.getBeanClass();
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction>() 
								@Override
								public Constructor run() throws Exception {
									return clazz.getDeclaredConstructor((Class[]) null);
								}
							});
						}
						else {
							constructorToUse =	clazz.getDeclaredConstructor((Class[]) null);
						}
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Throwable ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			// 通过BeanUtils进行实例化,这个BeanUtils的实例化通过Constructor来实例化Bean
			// 在BeanUtils中可以看到具体的调用ctor.newInstance(args)
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// 使用CGLIB进行对象的实例化
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}
2.populateBean()

我们再来看一下populateBean(),这个过程设计对各种Bean对象的属性处理过程,这些依赖关系处理的一局就是已经解析得到的BeanDefinition。

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

		if (bw == null) {
			if (!pvs.isEmpty()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			else {
				// 跳过空实例的属性填充阶段。 
				return;
			}
		}
		// 给任何InstantiationAwareBeanPostProcessors修改设置属性之前的状态 例如,它可以被用来支持字段注入的样式。 
		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);
			// 如果适用的话,添加基于名称的自动装配属性值。  
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// 如果适用的话,添加基于类型的自动装配的属性值。  
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}
		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) {
						//@Value@Autowired AutowiredAnnotationBeanPostProcessor的postProcessPropertyValues方法处理
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvs == null) {
							return;
						}
					}
				}
			}
			if (needsDepCheck) {
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}
		applyPropertyValues(beanName, mbd, bw, pvs);
	}

进入applyPropertyValues()方法中

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
		if (pvs == null || pvs.isEmpty()) {
			return;
		}
		if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
			((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
		}
		MutablePropertyValues mpvs = null;
		List original;
		if (pvs instanceof MutablePropertyValues) {
			mpvs = (MutablePropertyValues) pvs;
			if (mpvs.isConverted()) {
				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;
		}
		//  注意这个BeanDefinitionValueResolver对BeanDefinition的解析是在这个valueResolver中完成的
		BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
		// 这里为解析值创建一个副本,副本的数据将会被注入到Bean中
		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);
				}
				// 可能在合并的bean定义中存储转换后的值,
				// 为了避免对每个创建的bean实例进行重新转换。 
				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();
		}
		try {
			//这里是依赖注入发生的地方,会在BeanWrapperImpl中完成
			bw.setPropertyValues(new MutablePropertyValues(deepCopy));
		}
		catch (BeansException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Error setting property values", ex);
		}
	}
总结

在Bean的创建和对象依赖注入的过程中,需要依据BeanDefinition中的信息来递归完成依赖注入,从上面的几个递归过程中可以看到,这些递归都是以getBean为入口的,一个递归是在上下文体系中查找需要的Bean和创建Bean的递归调用,另一个递归是在依赖注入时,通过递归调用容器的getBean方法,得到当前Bean的依赖Bean,同时也出发对依赖Bean的创建和注入。在对Bean的属性进行依赖注入时,解析的过程也是一个递归的过程。这样根据依赖关系,一层层的完成Bean的创建和注入,直到最后完成当前Bean的创建。
在Bean创建和依赖注入完成以后,在IoC容器中建立起一系列依靠依赖关系联系起来的Bean,这个Bean已经不是简单的Java对象了,该Bean系列以及Bean之间的依赖关系建立完成之后,通过IoC容器的相关接口方法,就可以方便的供上层应用使用了。

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号