java源码 - Spring5.x(2)之 Bean的加载与创建

在这里插入图片描述

1. getBean

     HelloWorld helloWorld = actx.getBean(HelloWorld.class);

在这里插入图片描述
在org.springframework.beans.factory.BeanFactory中定义了几种获取Bean的方法,其中有通过.class,通过Bean的注册名和Object来获取Bean的方式。

org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String, java.lang.Class)

@Override
	public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
		return doGetBean(name, requiredType, null, false);
	}

最后其实委托给doGetBean方法执行逻辑:

	/**
	 * 返回指定bean的实例,该实例可以是共享的,也可以是独立的。
	 * @param 命名要检索的bean的名称
	 * @param 指定要检索的bean的必需类型
	 * @param args参数,当使用显式参数创建bean实例时使用
*(仅在创建新实例而不是检索现有实例时应用)
	 * @param typeCheckOnly是否为类型检查获取实例,
				*不作实际使用
	 * @return bean的实例
	 * @throws 如果bean不能被创建,则BeansException异常
	 */
	@SuppressWarnings("unchecked")
	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
		//提取对应的BeanName
		final String beanName = transformedBeanName(name);
		Object bean;

		// 检查单例缓存中手动注册的单例。
		//这里存在解决依赖注入的情况,而且依赖创建的时候为了避免循环依赖,
		//Spring创建bean的原则是不等bean创建完成就会创建bean的ObjectFactory提早曝光
		//也就是将ObjectFactory加入到缓存中,一旦下个bean创建的时候需要依赖上一个bean则直接使用ObjectFactory。
		
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			//返回对应的实例,有时候存在诸如BeanFactory的情况并不是直接返回实例本身而是返回方法返回的实例
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			//如果我们已经创建了这个bean实例,则失败:
			//我们可以假定是在循环引用中。
			//循环依赖 抛出异常
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new 
				BeanCurrentlyInCreationException(beanName);
			}

			// 检查此工厂中是否存在bean定义。
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// 未找到->检查父级。
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					// 使用显式参数委托给父级。
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
					// 没有args ->委托到标准getBean方法。
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}

			if (!typeCheckOnly) {
			//如果不是仅仅做类型检查则是创建bean,这里进行记录
				markBeanAsCreated(beanName);
			}

			try {
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				//保证初始化当前bean所依赖的bean。即递归实例化依赖的bean
				String[] dependsOn = mbd.getDependsOn();
				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 + "'");
						}
						//缓存依赖调用
						registerDependentBean(dep, beanName);
						try {
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// 创建bean实例。
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							//显式地从单例缓存中删除实例:它可能已经被放在那里了
							//热心由创建过程,以允许循环引用分辨率。
							//还删除接收到该bean临时引用的任何bean。
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				else if (mbd.isPrototype()) {
					// 它是一个原型->创建一个新实例。
					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 = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
					//prototype的创建bean
						Object scopedInstance = scope.get(beanName, () -> {
					
							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);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		// 检查required类型是否与实际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.isTraceEnabled()) {
					logger.trace("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

以上一段代码属于Spring中较为重量级的内容了。
下面再来归纳一下步骤:

  1. final String beanName = transformedBeanName(name);
    这一部分主要是转化beanName,其真实的名字其实是依靠于Spring内部的aliasMap,这个map初始化于Bean的注册阶段。一般返回的BeanName指向最终指向的Bean,例如:A-> B ,B-> C,那么最终返回C。

  2. Object sharedInstance = getSingleton(beanName);
    从缓存中获取单例,单例只会初始化一次。首先尝试从缓存中加载,如果加载不成功则再次尝试从singletonFactories中加载。因为在创建单例 bean 的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,在 Spring 中创建 bea 的原则是不等bean创建完成就会将创建 bean的ObjectFactory 提早曝光加入到缓存中, 一旦 bean 创建时候需要依赖上 bean直接接使用 ObjectFactory 。

  3. bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    这个方法主要是从工厂类中的工厂方法返回我们需要的bean。后面会详细看。

  4. isPrototypeCurrentlyInCreation(beanName);
    是否循环依赖。只有在单例的情况下才会尝试解决循环依赖。

  5. if (parentBeanFactory != null && !containsBeanDefinition(beanName))
    要知道我们当前的方法处于AbstractBeanFactory,要是parentBeanFactory 为空那么不用玩了。而containsBeanDefinition则是交给子类去查找当前配置是否包含beanName的配置。

  6. RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    将存储配置的 GernericBeanDefinition 转换为 RootBeanDefinition。

  7. String[] dependsOn = mbd.getDependsOn();
    bean初始化过程中很可能会用到某些属性,而某些属性很可能是动态配置的,并且配置成依赖于其他的 bean ,那么这个时候就有必要先加载依赖的 bean,所以,在 Spring加载顺序中,在初始化某 bean 的时候首先会初始化这个bean 所对应的依赖。

  8. mbd.isSingleton();mbd.isPrototype();
    针对不同的 scope 进行 bean 的创建;

  9. requiredType != null && !requiredType.isInstance(bean);
    类型转换,假如传入的参数包含目标类型,那么Spring会自动帮助我们进行类型转换。

2. FactoryBean

这是Spring提供的一个个性化的获取Bean的接口,用户可以定制实例化Bean的逻辑。学过工厂模式的都知道,这样的类应该是一个工厂类,只要实现了FactoryBean接口,那么该工厂所产生的类可以放入Spring容器中。

public interface FactoryBean<T> {
//返回由FactoryBean创建的Bean实例,如果isSingleton()返回true,
//则该实例会放到Spring实例缓存池中
	@Nullable
	T getObject() throws Exception;
//返回由 FactoryBean 创建的 bean 实例的作用域是Singleton还是prototype
	@Nullable
	Class<?> getObjectType();
	//返回 FactoryBean创建的bean类型
	default boolean isSingleton() {
		return true;
	}
}

3. getObjectForBeanInstance

在getBean方法中,getObjectForBeanInstance是一个高频方法,不存从哪里获取加载Bean,代码里都会调用这个方法来检测进一步的正确性,其实就是来检测一下当前Bean是否是FactoryBean的类型。如果是,那么需要调用该Bean对应的FactoryBean实例中的getObject作为返回值。

/**
	*获取给定bean实例的对象
*对于FactoryBean,实例本身或它创建的对象。
	 * @param 共享bean实例
	 * @param 可能包含工厂取消引用前缀的名称
	 * @param 规范bean名
	 * @param 合并的bean定义
	 * @return 要为bean公开的对象
	 */
	protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

		// 如果bean不是工厂,不要让调用代码尝试取消对工厂的引用。
		//如果name带有&前缀
		if (BeanFactoryUtils.isFactoryDereference(name)) {
			if (beanInstance instanceof NullBean) {
				return beanInstance;
			}
			//如果用户想要直接获取工厂实例而不是工厂的getObject方法对应的实例,那么传入的name应该带有&前缀
			if (!(beanInstance instanceof FactoryBean)) {
				throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
			}
		}

		//现在我们有了bean实例,它可能是一个普通的bean或一个FactoryBean。
		//如果它是FactoryBean,我们使用它来创建一个bean实例,除非
		//调用者实际上需要对工厂的引用。
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}

		Object object = null;
		if (mbd == null) {
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// 从工厂返回bean实例。
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			//如果是单例对象,则缓存从FactoryBean获得的对象。
			if (mbd == null && containsBeanDefinition(beanName)) {
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			//从factoryBean中解析Bean
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

以上代码的流程如下:

  1. 工厂Bean类型验证
  2. 如果是带有&的name,那么代表获取的是工厂实例,直接返回。
  3. 对Bean进行转换
  4. 从工厂方法获取出真正想要获取的Bean

解析来看看这个配置其实就懂以上代码了。

<bean  id= "car" class="com.xxx.xxx.CarFactory" carinfo="xxxxxx">

如果想要获取CarFactory实例,那么按照名称获取bean的时候应该是“&car”。

接下来看方法:

	/**
	*从给定的FactoryBean获取要公开的对象。
	 * @param 工厂FactoryBean实例
	 * @param beanName the name of the bean
	 * @param 是否应该对bean进行后处理
	 * @return 从FactoryBean获得的对象
	 * @throws如果FactoryBean对象创建失败,则出现BeanCreationException异常
	 * @see org.springframework.beans.factory.FactoryBean#getObject()
	 */
	protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
		if (factory.isSingleton() && containsSingleton(beanName)) {
			synchronized (getSingletonMutex()) {
				Object object = this.factoryBeanObjectCache.get(beanName);
				if (object == null) {
					object = doGetObjectFromFactoryBean(factory, beanName);
					//如果在上面的getObject()调用期间没有将其放入,则只进行后处理和存储
					//(例如,由于自定义getBean调用触发的循环引用处理)
					Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
					if (alreadyThere != null) {
						object = alreadyThere;
					}
					else {
						if (shouldPostProcess) {
							if (isSingletonCurrentlyInCreation(beanName)) {
								//暂时返回未后处理的对象,尚未存储。
								return object;
							}
							beforeSingletonCreation(beanName);
							try {
								object = postProcessObjectFromFactoryBean(object, beanName);
							}
							catch (Throwable ex) {
								throw new BeanCreationException(beanName,
										"Post-processing of FactoryBean's singleton object failed", ex);
							}
							finally {
								afterSingletonCreation(beanName);
							}
						}
						if (containsSingleton(beanName)) {
							this.factoryBeanObjectCache.put(beanName, object);
						}
					}
				}
				return object;
			}
		}
		else {
			Object object = doGetObjectFromFactoryBean(factory, beanName);
			if (shouldPostProcess) {
				try {
					object = postProcessObjectFromFactoryBean(object, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
				}
			}
			return object;
		}
	}
/**
	 * 从给定的FactoryBean获取要公开的对象。
	 * @param factory the FactoryBean instance
	 * @param beanName the name of the bean
	 * @return the object obtained from the FactoryBean
	 * @throws BeanCreationException if FactoryBean object creation failed
	 * @see org.springframework.beans.factory.FactoryBean#getObject()
	 */
	private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
			throws BeanCreationException {

		Object object;
		try {
			if (System.getSecurityManager() != null) {
				AccessControlContext acc = getAccessControlContext();
				try {
					object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
			//这里直接调用了factory.getObject()的方法来获取这个bean
				object = factory.getObject();
			}
		}
		catch (FactoryBeanNotInitializedException ex) {
			throw new BeanCurrentlyInCreationException(beanName, ex.toString());
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
		}

		//不要接受不完整的FactoryBean的空值
		//初始化:许多factorybean只返回null。
		if (object == null) {
			if (isSingletonCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(
						beanName, "FactoryBean which is currently in creation returned null from getObject");
			}
			object = new NullBean();
		}
		return object;
	}

由于之前获取到了工厂实例,那么他这里直接调用工厂实例的getObject方法。
除此之外还调用了前置后置的处理。

4. getSingleton

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)

	/**
	*返回在给定名称下注册的(raw)单例对象。
	检查已经实例化的单例,并且允许早期
	对当前创建的单例对象的引用(解决循环引用)。
	 * @param 要查找的bean的名字
	 * @param 早期参考是否应该建立
	 * @return 注册的单例对象,如果没有找到,则使用{@code null}
	 */
	@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        /**
         * 第一步:我们尝试去一级缓存(单例缓存池中去获取对象,一般情况从该map中获取的对象是直接可以使用的)
         * Spring IoC容器初始化加载单实例bean的时候第一次进来的时候 该map中一般返回空
         */
        Object singletonObject = this.singletonObjects.get(beanName);
        /**
         * 若在第一级缓存中没有获取到对象,并且singletonsCurrentlyInCreation正在创建的单实例的list包含该beanName
         * Spring IoC容器初始化加载单实例bean的时候第一次进来的时候 该list中一般返回空,但是循环依赖的时候可以满足该条件
         */
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                /**
                 * 尝试去二级缓存中获取对象(二级缓存中的对象是一个早期对象)
                 * 何为早期对象:就是bean刚刚调用了构造方法,还没给bean的属性进行赋值的对象就是早期对象
                 */
                singletonObject = this.earlySingletonObjects.get(beanName);
                /**
                 * 二级缓存中也没有获取到对象,allowEarlyReference为true(参数是有上一个方法传递进来的true)
                 */
                if (singletonObject == null && allowEarlyReference) {
                    /**
                     * 直接从三级缓存中获取ObjectFactory对象 这个对接就是用来解决循环依赖的关键所在
                     * 在getBean的过程中,当bean调用了构造方法的时候,把早期对象包裹成一个ObjectFactory暴露到三级缓存中
                     */
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    //从三级缓存中获取到对象不为空
                    if (singletonFactory != null) {
                        /**
                         * 在这里通过暴露的ObjectFactory包装对象中,通过调用他的getObject()来获取我们的早期对象
                         * 在这个环节中会调用到 getEarlyBeanReference()来进行后置处理
                         */
                        singletonObject = singletonFactory.getObject();
                        //把早期对象放置在二级缓存,
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        //ObjectFactory 包装对象从三级缓存中删除掉
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }

5. createBean

	/**
	这个类的中心方法:创建一个bean实例,
	*填充bean实例,应用后处理器,等等。
	* @see # doCreateBean
	*/
	@Override
	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;

		//确保bean类在此时被实际解析
		//在动态解析类的情况下克隆bean定义
		//不能存储在共享合并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 {
		//让BeanPostProcessors有机会返回代理而不是目标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 {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isDebugEnabled()) {
				logger.debug("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
		//之前检测到的异常已经包含了正确的bean创建上下文,
		//或非法的单例状态被传递到DefaultSingletonBeanRegistry。
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

以上代码主要做了这些事:

  1. 根据设置的class属性或者根据className来解析Class。
  2. 对override属性进行标记及验证。
  3. 应用初始化前的后处理器,解析指定bean是否存在初始化前的操作。
  4. 创建bean

创建实例前的前置处理

在调用docreate之前,Spring还执行了一组实例创建前的处理。其次接着还进行了一个return的判断。

	//给BeanPostProcessors一个返回代理而不是目标bean实例的机会。
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}

当经过前置处理后返回的结果如果不为空,那么会直接略过后续 bean 的创建而直接返回结果 这一特性虽然很容易被忽略,但是却起 至关重要的作用,我们熟知的 AOP 功能就是基于这里的判断的。

/**
	*应用实例化前的后处理程序,解析是否有
	*实例化之前指定bean的快捷方式。
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @return 简单确定的bean实例,如果没有,则为{@code null}
	 */
	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// 确保此时bean类已经被实际解析。
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

applyBeanPostProcessorsBeforeInstantiation,applyBeanPostProcessorsAfterInitialization,两个方法实现的非常简单,无非是对后处理器中的所有 lnstantiationAwareBeanPostProcessor类型的后处理器进行postProcessBeforelnstantiation方法和 BeanPostProcessor 的postProcessAfterInitialization方法的调用。

  1. 实例化前的后处理器调用
    bean的实例化前调用,也就是将 AbsractBeanDefinition 转换为 BeanWrapper 前的处理,给子类一个修改 BeanDefinition的机会,也就是说当程序经过这个方法后, bean 可能已经不是我们认为的 bean 是或许成为了 个经过处理的代理 bean ,可能是通过cglib 生成的,也可是通过其他技术生成的。
  2. 实例化后的后处理器应用
    Spring 中的规则是在 bean 的初始化后尽可能保证将注册的后处理器的postProcessAfterlnitialization 方法应用到该 bean 中,因为如果返回的 bean 不为空, 那么便不会再次经历普 bean 的创建过程,所以只能在这里应用后处理器postProcessAfterInitialization方法。

6. 循环依赖

什么是循环依赖?

循环依赖就是循环引用,就 两个或多个 bean 相互之间的持有对方,比如 Circ eA 引用CircleB ,CircleB 引用 CircleC, CircleC 引用 CircleA ,则它们最终反映为个环。

Spring解决循环依赖

Spring中将循环依赖的处理分成了3种情况:

  1. 构造器循环依赖
    通过构造器注入构成的循环依赖, 此依赖是无法解决的 ,只能抛出BeanCurrentylnCreationException 异常表示循环依赖。
    例如:Spring容器先创建单例A,A依赖B,然后将A放在“当前创建Bean池”中,此时创建B,B依赖C ,然后将B放在“当前创建Bean池”中,此时创建C,C又依赖A, 但是,此时A已经在池中,所以会报错,因为在池中的Bean都是未初始化完的,所以会依赖错误。
  2. setter循环依赖
    表示通过 setter 注入方式构成的循环依赖。对于setter注入造成的依赖通过 Spring 容器提前暴露刚完成构造器注入,但未完成其他步骤(如 setter 注入)的 bean 来完成的,而且只能解决单例作用域的 bean 循环依赖 通过提前暴露一个单例工厂方法,从而使其他 bean 能引用到该bean。
    Spring先是用构造实例化Bean对象 ,此时Spring会将这个实例化结束的对象放到一个Map中,并且Spring提供了获取这个未设置属性的实例化对象引用的方法。

解决示例:
Spring根据无参构造先创建一个单例A,并暴露一个ObjectFactory 用于返回一个创建中的bean,并将A标识符放入当前创建bean池,然后进行setter注入 B。
Spring根据无参构造创建一个单例B,并暴露一个ObjectFactory 用于返回一个创建中的bean,将B标识符放入当前创建bean池,然后进行setter注入C。

Spring根据无参构造创建一个单例C,并暴露一个ObjectFactory 用于返回一个创建中的bean,将C标识符放入当前创建bean池,然后进行setter注入A。
进行注入A时,由于提前暴露了ObjectFactory工厂,从而使用它返回提前暴露的一个创建中的bean。

最后,依赖注入B,A,完成setter注入。
在这里插入图片描述

对于“singleton 作用 bean ,可以通过setAllowCircularReferences(false) ;来禁用循环引用。

  1. prototype 范围的依赖处理
    对于“prototype ”作用域 bean, Spring 容器无法完成依赖注入,因为 Spring 容器不进行缓存“prototype ”作用域的 bean ,因此无法提前暴露一个创建中的 bean。

7. doCreateBean

接着 5. createBean
当经历resolveBeforelnstantiation 方法后,程序有两个选择,如果创建了代理或者重写了InstantiationAwareBeanPostProcessorpostProcessBeforelnstantiation 方法并在 postProcessBeforelnstantiation 中改变了 bean 直接返回就可以了。否则则需要进行 bean 的创建。常规 bean 的创建是在doCreateBean完成的。

/**
	实际创建指定的bean。创建前的处理已经发生
	*在这里,例如检查{@code postProcessBeforeInstantiation}回调。
	*
	区分默认的bean实例化,a的使用
	*工厂方法,并自动装配构造函数。
	 * @param beanName the name of the bean
	 * @param bean的合并bean定义
	 * @param 用于构造函数或工厂方法调用的显式参数
	 * @return bean的一个新实例
	 * @throws 如果无法创建bean,则出现BeanCreationException异常
	 * @see #instantiateBean
	 * @see #instantiateUsingFactoryMethod
	 * @see #autowireConstructor
	 */
	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {

		// 实例化bean。
		BeanWrapper instanceWrapper = null;
		//清楚单例缓存
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
		//根据指定的bean使用对应的策略创建新的实例
		//如工厂方法,构造函数自动注入,简单初始化
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			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");
			}
			//为了避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
			//注意这个方法getEarlyBeanReference
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		//初始化bean实例。
		Object exposedObject = bean;
		try {
		//对bean进行填充,将各个属性注入,其中,可能存在依赖于其他bean的属性,则会递归初始依赖bean
			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);
				//earlySingletonReference 只有在检测到有循环依赖的时候才不为空
			if (earlySingletonReference != null) {
		
			//exposedObject == bean说明没有被增强 
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
					//检测依赖
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					/*
					因为bean创建后其所依赖的bean一定是已经创建的
					actualDependentBeans不为空表示当前bean创建后其依赖的bean却没有全部创建完,也就是说明存在循环依赖。
					*/
					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.");
					}
				}
			}
		}

	//将bean注册为一次性的。
		try {
		//根据scope注册bean
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}
/**
		*获取对指定bean的早期访问的引用,
		*通常用于解决循环引用。
	 * @param bean的名称(用于错误处理目的)
	 * @param bean的合并bean定义
	 * @param bean the raw bean instance
	 * @return 要公开为bean引用的对象
	 */
	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					//aop就是在这里将advice织入bean中的。
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				}
			}
		}
		return exposedObject;
	}

doCreateBean的流程如下:

  1. 如果是单例则要先清除缓存。
  2. 实例化bean,将BeanDefinition转换为BeanWrapper。
  • 如果存在工厂方法则进行工厂方法的初始化
  • 一个类有多个构造函数,需要根据参数来初始化
  • 以上均没有,则使用默认构造函数
  1. MergedBeanDefinitionPostProcessor的应用
    bean 合并后的处理, Autowired 注解正是通过此方法实现诸如类型的预解析。
  2. 依赖处理
    解决办法提前暴露一个ObjectFactory来处理。
  3. 属性填充
    将所有依赖属性填充进bean的实例中。
  4. 循环依赖检查
    在这个步骤里面会检测已经加载的 bean 是否已经出现了依赖循环,并判断是再需要抛出异常。
  5. 注册 DisposableBean
    如果配 destroy-method ,这里需要注册以便于在销毁时候调用。
  6. 完成创建井返回

创建bean的实例

/**
	*为指定的bean创建一个新的实例,使用适当的实例化策略:
	*工厂方法,构造函数自动装配,或简单实例化。
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @param 用于构造函数或工厂方法调用的显式参数
	 * @return 一个新实例BeanWrapper
	 * @see #obtainFromSupplier
	 * @see #instantiateUsingFactoryMethod
	 * @see #autowireConstructor
	 * @see #instantiateBean
	 */
	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable 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());
		}

		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}
		//如果工厂方法不为空,则使用工厂方法初始化策略
		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() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
				//构造函数自动注入
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// 无需特殊处理:只需使用无参数的构造函数。
		return instantiateBean(beanName, mbd);
	}

流程如下:

  1. 如果在RootBeanDefinition中存在factoryMethodName属性,或者说在配置文件中配置了工厂方法,那么Spring会尝试使用instantiateUsingFactoryMethod根据RootBeanDefinition生成Bean实例。
  2. 解析构造函数并进行构造函数的实例化,因为一个 bean 对应的类中可能会有多个构造函数,而每个构造函数的参数不同, Spring 在根据参数及类型去判断最终会使用哪个构造函数进行实例化。其判断过程采用缓存机制,是一个比较消耗性能的过程。

接下来看其解析构造函数的几种方法:

  1. autowireConstructor
protected BeanWrapper autowireConstructor(
			String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {

		return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
	}
public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
			@Nullable Constructor<?>[] chosenCtors, @Nullable final Object[] explicitArgs) {

		BeanWrapperImpl bw = new BeanWrapperImpl();
		this.beanFactory.initBeanWrapper(bw);

		Constructor<?> constructorToUse = null;
		ArgumentsHolder argsHolderToUse = null;
		Object[] argsToUse = null;
		//explicitArgs  通过 getBean 方法传人
	//如果 getBean 方法调用的时候指定方法参数那么直接使用
		if (explicitArgs != null) {
			argsToUse = explicitArgs;
		}
		else {
		//如果在getBean 方法时候没有指定则尝试从配置文件中解析
			Object[] argsToResolve = null;
			//尝试从缓存中获取
			synchronized (mbd.constructorArgumentLock) {
				constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse != null && mbd.constructorArgumentsResolved) {
					// Found a cached constructor...
					argsToUse = mbd.resolvedConstructorArguments;
					if (argsToUse == null) {
					//配置的构造函数
						argsToResolve = mbd.preparedConstructorArguments;
					}
				}
			}
			//如果缓存中存在
			if (argsToResolve != null) {
			//解析参数类型,如给定方法的构造函数A(int,int)则通过此方法就会把配置中的(”1“,”1“)转换成(1,1)
			//缓存中的值可能是原始值也可能是最终值
				argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
			}
		}
			//没有被缓存
		if (constructorToUse == null) {
			// 需要解析构造函数。
			boolean autowiring = (chosenCtors != null ||
					mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
			ConstructorArgumentValues resolvedValues = null;

			int minNrOfArgs;
			if (explicitArgs != null) {
				minNrOfArgs = explicitArgs.length;
			}
			else {
			//提取配置文件中的配置的构造函数参数
				ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
				//用于承载解析后的构造函数参数的值
				resolvedValues = new ConstructorArgumentValues();
				//能解析到的参数个数
				minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
			}

			// 指定构造函数(如果有的话)。
			Constructor<?>[] candidates = chosenCtors;
			if (candidates == null) {
				Class<?> beanClass = mbd.getBeanClass();
				try {
					candidates = (mbd.isNonPublicAccessAllowed() ?
							beanClass.getDeclaredConstructors() : beanClass.getConstructors());
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Resolution of declared constructors on bean Class [" + beanClass.getName() +
							"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
				}
			}
			//将给定的构造函数排序
			//public构造函数优先参数降序,其次非public参数个数降序
			AutowireUtils.sortConstructors(candidates);
			int minTypeDiffWeight = Integer.MAX_VALUE;
			Set<Constructor<?>> ambiguousConstructors = null;
			LinkedList<UnsatisfiedDependencyException> causes = null;

			for (Constructor<?> candidate : candidates) {
				Class<?>[] paramTypes = candidate.getParameterTypes();

				if (constructorToUse != null && argsToUse.length > paramTypes.length) {
					//已经找到可以满足的贪心构造函数->
					//不要再往下看了,只剩下贪心构造函数了。
					break;
				}
				if (paramTypes.length < minNrOfArgs) {
				//参数个数不符合
					continue;
				}

				ArgumentsHolder argsHolder;
				if (resolvedValues != null) {
				//有参数则根据值构造对应参数类型的参数
					try {
					//注释上获取参数名称
						String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
						if (paramNames == null) {
						//获取参数名称探索器
							ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
							if (pnd != null) {
							//获取指定构造函数的参数名称
								paramNames = pnd.getParameterNames(candidate);
							}
						}
						//根据名称和数据类型创建参数持有者
						argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
								getUserDeclaredConstructor(candidate), autowiring);
					}
					catch (UnsatisfiedDependencyException ex) {
						if (logger.isTraceEnabled()) {
							logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
						}
						// 吞下并尝试下一个构造函数。
						if (causes == null) {
							causes = new LinkedList<>();
						}
						causes.add(ex);
						continue;
					}
				}
				else {
					// 给出的显式参数->参数长度必须精确匹配。
					if (paramTypes.length != explicitArgs.length) {
						continue;
					}
					//构造函数没有参数的情况
					argsHolder = new ArgumentsHolder(explicitArgs);
				}
			///探测是否有不确定性的构造函数存在 例如不同构造函数的参数为父子关系
				int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
						argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
				//选择这个构造函数,如果它表示最接近的匹配。
				if (typeDiffWeight < minTypeDiffWeight) {
					constructorToUse = candidate;
					argsHolderToUse = argsHolder;
					argsToUse = argsHolder.arguments;
					minTypeDiffWeight = typeDiffWeight;
					ambiguousConstructors = null;
				}
				else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
					if (ambiguousConstructors == null) {
						ambiguousConstructors = new LinkedHashSet<>();
						ambiguousConstructors.add(constructorToUse);
					}
					ambiguousConstructors.add(candidate);
				}
			}

			if (constructorToUse == null) {
				if (causes != null) {
					UnsatisfiedDependencyException ex = causes.removeLast();
					for (Exception cause : causes) {
						this.beanFactory.onSuppressedException(cause);
					}
					throw ex;
				}
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Could not resolve matching constructor " +
						"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
			}
			else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Ambiguous constructor matches found in bean '" + beanName + "' " +
						"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
						ambiguousConstructors);
			}

			if (explicitArgs == null) {
			//将解析的构造函数加入缓存
				argsHolderToUse.storeCache(mbd, constructorToUse);
			}
		}

		try {
			final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
			Object beanInstance;

			if (System.getSecurityManager() != null) {
				final Constructor<?> ctorToUse = constructorToUse;
				final Object[] argumentsToUse = argsToUse;
				beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
						strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
						beanFactory.getAccessControlContext());
			}
			else {
				beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
			}
			//将构造的实例加入BeanWrapper
			bw.setBeanInstance(beanInstance);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean instantiation via constructor failed", ex);
		}
	}

其功能概要如下:

  • 构造函数参数的确定。
    1)根据 explicitArgs 参数判断
    如果explicitArgs不为空,那么可以直接确定参数,因为explicitArgs是在BeanFactory中调用getBean时指定的。而explicitArgs就可以确定bean所在类的构造函数或者工厂方法。
    2)缓存中获取
    3)配置文件获取
    如果不能在1),2)中获取到构造参数的信息,那么只能在配置文件中获取。

  • 构造函数的确定
    匹配的方法就是根据参数个数匹配,所以在匹配之前需要先对构造函数按照 public 构造函数优先参数数量降序、 非public构造函数参数数量降序。这样可以在遍历的情况下迅速判断排在后面的构造函数参数个数是否符合条件。
    其次,还可以根据给定的名称进行构造函数的确定。
    获取参数名称的方式有:注解方式,其次就是Spring工具类ParameterNameDiscoverer。

  • 根据对应的构造函数转换对应的参数类型。

  • 构造函数不确定性的验证。

  • 根据实例化策略以及得到的构造函数及构造函数实例化Bean。


  1. instantiateBean
/**
	*使用给定bean的默认构造函数实例化它。
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @return a BeanWrapper for the new instance
	 */
	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);
		}
	}
  1. 实例化策略
    org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate
@Override
	public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
		// 如果没有重写,不要用CGLIB重写类。
//如果有需 者动态替换的方 需要使用 cg lib 行动态代理,因为可以在创建代理的同时
//将动态方法织人类
//但是如果没有需要动态改变得方法 方便直接反射就可以了
		if (!bd.hasMethodOverrides()) {
			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(
									(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
						}
						else {
							constructorToUse =	clazz.getDeclaredConstructor();
						}
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Throwable ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// 必须生成CGLIB子类。
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}

创建bean的ObjectFactory

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

	// 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, () -> getEarlyBeanReference(beanName, mbd, bean));
		}



	/**
	 *获取对指定bean的早期访问的引用,
	 *通常用于解决循环引用。
	 * @param bean的名称(用于错误处理目的)
	 * @param mbd the merged bean definition for the bean
	 * @param bean the raw bean instance
	 * @return the object to expose as bean reference
	 */
	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				}
			}
		}
		return exposedObject;
	}

earlySingletonExposure:提早曝光的单例。
mbd.isSingleton():此RootBeanDefinition 代表的是否是单例。
this.allowCircularReferences:是否允许循环依赖。
isSingletonCurrentlylnCreation(beanName):该 bean 是否在创建中。Spring中,会有个专门的属性 认为 DefaultSingletonBeanRegistry的singletonsCurrentlyInCreation来记录bean的加载状态,在 bean 开始创建会将 beanName 记录在属性中,在 bean 创建结束后会将 beanName 从属性中移除。

循环依赖解决三要素:是否单例,是否允许循环依赖,对应bean是否处于创建状态。

在这里插入图片描述
这里最关键的就是ObjectFactory的创建:

ObjectFactory定义一个可以返回一个对象实例的工厂(可能是共享的或独立的)。

	addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

--------------------------------------

	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				}
			}
		}
		return exposedObject;
	}

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		synchronized (this.singletonObjects) {
			if (!this.singletonObjects.containsKey(beanName)) {
				this.singletonFactories.put(beanName, singletonFactory);
				this.earlySingletonObjects.remove(beanName);
				this.registeredSingletons.add(beanName);
			}
		}
	}

getEarlyBeanReference除了后处理的调用外没有别的处理工作。


属性注入populateBean

在这里插入图片描述

/**
	 *用属性值填充给定BeanWrapper中的bean实例
	 *来自bean定义。
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @param bw the BeanWrapper with bean instance
	 */
	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 {
				//跳过null实例的属性填充阶段。
				return;
			}
		}

		//给任何实例化awarebeanpostprocessor修改的机会
		//属性设置前bean的状态。
		//支持字段注入的样式。
		boolean continueWithPropertyPopulation = true;

		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					//返回值为是否继续填充 bean
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}
		//如果后处理器发出停止填充命令则终止后续的执行
		if (!continueWithPropertyPopulation) {
			return;
		}

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			// 根据autotowire的名称(如适用)添加属性值。
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}

			// 根据自动装配的类型(如果适用)添加属性值。
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}

			pvs = newPvs;
		}
		//后处理器已经初始化
		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) {
			//依赖检查,对应depends-on属性
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}

		if (pvs != null) {
		//将属性应用到bean中
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

处理流程如下:

  1. InstantiationAwareBeanPostProcessor处理器的postProcessAfterInstantion函数的应用,此函数可以控制程序是否继续进行属性填充。
  2. 根据注入类型(byName/byType),提取依赖的bean,并统一存入PropertyValues中。
  3. 执行postProcessPropertyValues方法,对属性获取完毕前对属性再次处理。
  4. 将PropertyValues中的属性填充至BeanWrapper中。

接下来看看autowireByName与autowireByType

  1. autowireByName
	protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			if (containsBean(propertyName)) {
				Object bean = getBean(propertyName);
				pvs.add(propertyName, bean);
				registerDependentBean(propertyName, beanName);
				if (logger.isDebugEnabled()) {
					logger.debug("Added autowiring by name from bean name '" + beanName +
							"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
							"' by name: no matching bean found");
				}
			}
		}
	}

  1. autowireByType
protected void autowireByType(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}

		Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			try {
				PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
				//不要尝试按类型自动装配类型对象:永远没有意义,
				//即使从技术上讲,这是一种不令人满意的、不简单的财产。
				if (Object.class != pd.getPropertyType()) {
					MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
					//在有优先级的后处理程序的情况下,不允许急于初始化来进行类型匹配。
					boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
					DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
					Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
					if (autowiredArgument != null) {
						pvs.add(propertyName, autowiredArgument);
					}
					for (String autowiredBeanName : autowiredBeanNames) {
						registerDependentBean(autowiredBeanName, beanName);
						if (logger.isDebugEnabled()) {
							logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
									propertyName + "' to bean named '" + autowiredBeanName + "'");
						}
					}
					autowiredBeanNames.clear();
				}
			}
			catch (BeansException ex) {
				throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
			}
		}
	}

初始化Bean

在这里插入图片描述

	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

激活 Aware 方法

Spring中实现Aware接口的Bean在被初始化后,即被Spring注入。

BeanPostProcessor

在调用客户初始化方法前以及调用自定义初始化方后分别会调用BeanPostProcesor的postProcessBeforelnitialization和postProcessAfterlnitialization方法 ,使用可以根据自己的务需进行响应的处理。

@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

激活自定义的 init 方法(InitializingBean)

除了使用配置的init-method外,还有InitializingBean接口,并在afterPropertiesSet 实现自己 的初始化业务逻辑。

public interface InitializingBean {
	/**
	* BeanFactory在设置了提供的所有bean属性后调用
	*(满足BeanFactoryAware和applicationcontext taware)。
	这个方法只允许bean实例执行初始化
	*可能当所有的bean属性已经被设置,并抛出一个
	*配置错误时的异常。
	* @抛出异常的事件,错误的配置(如
	*表示设置基本属性失败)或初始化失败。
	*/
	void afterPropertiesSet() throws Exception;
}

	protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
			throws Throwable {

		boolean isInitializingBean = (bean instanceof InitializingBean);
		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
			if (logger.isDebugEnabled()) {
				logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
			}
			if (System.getSecurityManager() != null) {
				try {
					AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
						((InitializingBean) bean).afterPropertiesSet();
						return null;
					}, getAccessControlContext());
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
				((InitializingBean) bean).afterPropertiesSet();
			}
		}

		if (mbd != null && bean.getClass() != NullBean.class) {
			String initMethodName = mbd.getInitMethodName();
			if (StringUtils.hasLength(initMethodName) &&
					!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
					!mbd.isExternallyManagedInitMethod(initMethodName)) {
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}
	}

注册 DisposableBean

Spring 中不但提供了对于初始化方法的扩展 同样也提供了销毁方 的扩展入口,对于销毁方法的扩展,除了我 熟知的配 destroy -method 方法外,用户还可以注册后处理DestructionAwareBeanPostProcessor 处理 bean 的销毁方法。

在这里插入图片描述

	protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
		AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
		if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
			if (mbd.isSingleton()) {
				//注册一个执行所有销毁的一次性bean实现
		//为给定bean工作:DestructionAwareBeanPostProcessors,
		//可处理bean接口,自定义销毁方法。
				registerDisposableBean(beanName,
						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
			}
			else {
				//自定义scope的处理
				Scope scope = this.scopes.get(mbd.getScope());
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
				}
				scope.registerDestructionCallback(beanName,
						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
			}
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值