spring源码系列6——spring启动流程4

        前面系列3、系类4、系列5分析了spring如何找到交给它管理的类以及如何将所管理的类用beanDefintion进行表示并存储在beanDefinitionMap中。bean的生成主要可以分成两个阶段:实例化和初始化。本节只分析实例化过程,下一节分析初始化过程。发车!

1、preInstantiateSingletons

A、遍历beanDefinitionNames,然后根据beanName从beanFactory得到beanDefinition。如果此beanDefinition为非抽象、单例、非加载,则针对此beanDefinion生成bean;

B、判断是否属于FactoryBean,如果是则执行特殊逻辑(factoryBean后续作为专题分析),否则执行下面getBean方法;

//name为beanName
public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

2、doGetBean

protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
        //主要针对factoryBean的beanName,去掉前缀&
		String beanName = transformedBeanName(name);//关键步骤1
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);//关键步骤2
		if (sharedInstance != null && args == null) {
	         //省略非关键代码
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				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 if (requiredType != null) {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}

			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			try {
				//返回RootBeanDefinition
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				String[] dependsOn = mbd.getDependsOn();//关键步骤3
				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 + "'");
						}
						//注册dep和beanName的依赖关系
						registerDependentBean(dep, beanName);//关键步骤4
						try {//优先实例化被依赖的bean
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// Create bean instance.
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {//关键步骤5
						try {
							//回调lamba表达式
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
				//省略非关键代码
			}
		//省略非关键代码
		}

备注:

  • 关键步骤1
    此处主要是处理beanName,针对factoryBean name,去掉前面的&

  • 关键步骤2
    此处主要针对getSingleton进行解释,根据beanName从缓存中获取bean

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// Quick check for existing instance without full singleton lock
		/**
		 * 三级缓存:
		 * 单例池:singletonObjects
		 * 二级缓存—earlySingletonObjects
		 * 三级缓存—singletonFactories
		 */
		Object singletonObject = this.singletonObjects.get(beanName);
		//isSingletonCurrentlyInCreation判断当前beanName是否属于创建中
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			//从早期曝光集合获取
			singletonObject = this.earlySingletonObjects.get(beanName);
			if (singletonObject == null && allowEarlyReference) {
				synchronized (this.singletonObjects) {
					// Consistent creation of early reference within full singleton lock
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {

						singletonObject = this.earlySingletonObjects.get(beanName);
						if (singletonObject == null) {
							//从三级缓存中获取lamba表达式
							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							if (singletonFactory != null) {
								//执行lamba表达式
								singletonObject = singletonFactory.getObject();
								//放入早期曝光集合中
								this.earlySingletonObjects.put(beanName, singletonObject);
								//从三级缓存中移除beanName
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		return singletonObject;
	}
  • 关键步骤3
    此处循环依赖主要是指@DependOn注解设定的依赖关系

    通过获取注解的value值得到当前类所依赖的bean,优先生成依赖bean。在生成前检测是否产生死循环以及维护依赖关系,主要采用以下两个map结构:

    //当前beanName被哪些beanNames依赖
	/** Map between dependent bean names: bean name to Set of dependent bean names. */
	private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

	//beanName依赖哪些beanNames
	/** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */
	private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);


判断是否产生循环依赖:

	private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
		if (alreadySeen != null && alreadySeen.contains(beanName)) {
			return false;
		}
		String canonicalName = canonicalName(beanName);
		//获取beanName被哪些beanNames依赖
		Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
		if (dependentBeans == null) {
			return false;
		}
		/**
		 * beanName:A1
		 * dependentBeanName:A2
		 * A1依赖A2
		 * A2依赖A1
		 * A1被A2依赖,则dependentBeans包含A2,则形成死循环
		 */
		if (dependentBeans.contains(dependentBeanName)) {
			return true;
		}
		//判断链式依赖:A1->A2->....>A1
		for (String transitiveDependency : dependentBeans) {
			if (alreadySeen == null) {
				alreadySeen = new HashSet<>();
			}
			alreadySeen.add(beanName);//transitiveDependency依赖beanName
			if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
				return true;
			}
		}
		return false;
	}

依赖关系维护:

public void registerDependentBean(String beanName, String dependentBeanName) {
		String canonicalName = canonicalName(beanName);
        //dependentBeanMap记录beanName被dependentBeanName依赖
		synchronized (this.dependentBeanMap) {
			Set<String> dependentBeans =
					this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
			if (!dependentBeans.add(dependentBeanName)) {
				return;
			}
		}
		//dependenciesForBeanMap记录dependentBeanName依赖canonicalName依赖
		synchronized (this.dependenciesForBeanMap) {
			Set<String> dependenciesForBean =
					this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
			dependenciesForBean.add(canonicalName);
		}
	}

3、getSingleton

         此处主要分析doGetBean中关键步骤5处的getSingleton方法。

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		synchronized (this.singletonObjects) {
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				//创建和销毁冲突
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
				//回调前:将当前beanName加入singletonsCurrentlyInCreation,如果已在创建过程中则抛出异常
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					//执行回调函数
					singletonObject = singletonFactory.getObject();//
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
				//省略非关键代码
				}
				catch (BeanCreationException ex) {
				//省略非关键代码
					throw ex;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					//回调后:从singletonsCurrentlyInCreation移除beanName
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					//从二级、三级缓存移除,并将当前实例加入单例池中
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

        主要思想:从单例池中获取bean,如果存在则返回,否则执行回调函数生成。在创建前后分别执行beforeSingletonCreation和afterSingletonCreation方法,通过以下集合中标记当前bean正在创建中(也是判断循环依赖的关键)。接下来回调函数createBean。。

//正在创建的bean集合
	/** Names of beans that are currently in creation. */
	private final Set<String> singletonsCurrentlyInCreation =Collections.newSetFromMap(new ConcurrentHashMap<>(16));

4、createBean

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

		if (logger.isTraceEnabled()) {
			logger.trace("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) {
         //省略非关键代码
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			/**
			 * InstantiationAwareBeanPostProcessor
			 * postProcessBeforeInstantiation
			 * postProcessAfterInstantiation
			 *
			 * 如果能返回bean 则直接返回
			 */
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
		   //省略非关键代码
		}
		try {
			//真正的创建bean
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
          //省略非关键代码
		}
	}

        createBean主要逻辑:A、从beanDefinition中解析处理class;2、判断是否存在InstantiationAwareBeanPostProcessor( InstantiationAwareBeanPostProcessor继承BeanPostProcessor,作为后续bean生命周期的重要拓展点),如果存在则执行postProcessBeforeInstantiation方法返回bean,后续的逻辑则不再执行。下面来看doCreatBean(do**才是真正干活的开始)

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

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//通过反射创建实例
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
       //实例化代码后续分析
}

        通过反射进行对象实例化涉及到构造函数的选择,此处不作深入分析,后续作为专题分析;

5、总结

        本节分析refresh中的finishBeanFactoryInitialization方法,遍历beanDefinitionNames,针对单例懒加载的beanDefinition进行实例化,过程中涉及bean生命周期拓展接口InstantiationAwareBeanPostProcessor。下一节分析初始化过程,敬请期待。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值