从宏观角度分析Spring源码之DI

上篇文章讲解了IOC容器的初始化,将所有需要加载的Bean的定义(BeanDefinition)放入到了beanDefinitionMap中以等待后续的实例化和依赖注入。翻过源码的铁子们一定知道Bean的实例化和依赖注入过程的调用链非常繁杂,为了便于理解,将抛弃Spring框架中对细节的处理,从源码中抽取一条鲜明且具有代表性的主线进行分析。

1、概念

DI的全称是Dependency Injection,即依赖注入。通俗点来说,在A对象被创建的时候,由容器动态地将A所依赖的其他对象的引用注入进来。例如:Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过容器控制程序来将B对象在外部new出来并注入到A类里的引用中。

2、DI流程描述

  依赖注入主要有两大步骤来实现:

(1)Bean的实例化

(2)Bean属性的依赖注入

3、DI源码分析

首先要明确一点,依赖注入的过程是第一次调用getBean()方法的时候触发的,但是,如果设置了lazy-init属性为false,依赖注入的过程会由IOC容器直接完成。

废话少说,直接上时序图:

通过时序图能清晰地看到依赖注入的整个调用流程, 一般情况下我们会通过ApplicationContext来调用getBean()方法,然而打开源码一看getBean()方法是由ApplicationContext的父接口BeanFactory定义的,这就是依赖注入发生的起点。在整个调用链条中,依赖注入最主要的两个方法是createBeanInstance()和populateBean(),下面着重分析下这两个方法。

在createBeanInstance()方法中对Bean进行了实例化,即生成了Bean的对象,这个Bean实例的生成有不同的方式,可以通过工厂模式生成,也可以构造函数生成,采用哪种生成方式是由BeanDefinition来决定的。来看下createBeanInstance()的源码:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure bean class is actually resolved at this point.
		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());
		}

		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}
        //使用工厂方法对Bean进行实例化
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same 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);
			}
		}

		// Candidate constructors for autowiring?
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// Preferred constructors for default construction?
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		// No special handling: simply use no-arg constructor.
		return instantiateBean(beanName, mbd);
	}

而最常用的实例化方法是通过 instantiateBean()来完成的,如下:

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			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);
		}
	}

使用默认的策略对Bean进行实例化,查看源码可以发现,默认实例化策略是使用CGLIB动态代理对Bean进行实例化的。 

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {

	/** Strategy for creating bean instances. */
	private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

通过createBeanInstance()方法的调用完成了Bean的实例化过程,在实例化结束后还需要将Bean对象的依赖关系设置好,才能完成整个依赖注入过程,接下来分析依赖注入方法populateBean(),该方法在AbstractAutowireCapableBeanFactory中,源码如下:

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.
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						return;
					}
				}
			}
		}
            //获取beanDefinition中设置的property值
		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
            //开始依赖注入
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable.
                //根据name进行注入
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable.
                //根据type进行注入
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}

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

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

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

通过源码可以看到依赖注入方式有name注入和type注入两种方式,最后调用applyPropertyValues(beanName, mbd, bw, pvs)方法对Bean依赖的属性进行赋值,至此完成依赖注入过程。

由于是站在宏观的角度来分析Spring的源码,主要是把握主线思路,细节是不做讲解的,如有需要可以留言进行讨论。下篇文章将对Spring的AOP源码实现进行分析!

猜你喜欢

转载自blog.csdn.net/qq_27324761/article/details/105940919
今日推荐