SpringFramework的核心:IOC容器的实现------IoC容器的依赖注入

版权声明: https://blog.csdn.net/qq1641530151/article/details/82985497

如果IoC容器已经载入了用户定义的Bean信息,并开始分析依赖注入的原理。依赖注入是用户第一次向IoC容器索要Bean时触发的,当然也有例外。如果我们设置了lazy-init的属性。是可以在刚开始初始化容器的时候就为我们生成新的bean。

首先我们从DefaultListableBeanFactory类中来查看getBean触发的依赖注入

org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(String, Class<T>, Object[], boolean)

getBean方法里面都调用了doGetBean这个方法

由于这个方法非常非常长,所以我就不再粘贴出来。而是从这个方法里面找寻一些有用的信息。

doGetBean是一个很漫长的过程。而且根据我们创建的bean的要求不同,会有不同的创建方法。

首先我们要去缓存中去取,处理已经被创建过的单例模式的bean,对这种bean的请求不需要重复创建。

关于这样一行代码,是FactoryBean对于我们的实体bean的一个修饰作用

bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

接下里就是对BeanDefinition在IoC容器的查找存在,如果当前的IoC容器不存在那么就要去它的父类进行查找。如果最后没有查找结果。

取得bean以及这个bean所依赖的所有bean之后,我们就需要根据bean的创建要求来进行生成bean。

一种是Singleton bean,一种是prototype bean(这种bean每一次请求都会有一个新的对象产生)

最后我们要对创建出来的bean进行类型检查,如果没有问题,就把我们创建出来的bean返回。

现在我们主要来看看依赖注入的关键步骤,怎样根据BeanDefinition来生成对应的bean。接下来要进入到createBean中来具体进行说明。

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])

@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, 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.
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		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.
			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);
		}

		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}

具体的我们进入到createBean中来查看

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(String, RootBeanDefinition, Object[])

BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}

首先我们创建一个BeanWrapper来斥候我们的bean对象,如果是singleton,先把缓存中的同名bean清除。

具体的创建交给createBeanInstance来完成

之后就是对bean的初始化,依赖注入。这个主要是交给populateBean()方法来完成.

当实例化bean对象生成的基础上,spring需要对这些对象进行处理,各种bean对象生成以后,怎样把这些bean对象的依赖关系设置好,完成整个依赖注入的过程。这里涉及对各种对象Bean的属性的处理过程。

依赖注入过程,先处理autowire注入 。之后对属性的具体注入是在

applyPropertyValues(beanName, mbd, bw, pvs);

中完成的

现在进入到applyPropertyValues中去看看具体的对属性进行解析然后注入的过程

首先我们获取到了这个bean所需要的所有属性

		if (pvs == null || pvs.isEmpty()) {
			return;
		}

		MutablePropertyValues mpvs = null;
		List<PropertyValue> original;

		if (System.getSecurityManager() != null) {
			if (bw instanceof BeanWrapperImpl) {
				((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());
		}

然后我们对我们的这个original链表进行一次拷贝。

之后我们需要获取一系列的转换器用来将我们的BeanDefinition内的数据以及生成的bean对象进行依赖注入

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

		// Create a deep copy, resolving any references for values.
		List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(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);
				}
				// 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();
		}

之后是关于bean的属性的解析和注入,可以从书上进行查看相关的源码。

猜你喜欢

转载自blog.csdn.net/qq1641530151/article/details/82985497