欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

浅谈 SpringBean的初始化之 Bean创建准备 ---主线逻辑 ( 三 )

程序员文章站 2022-05-24 16:11:56
...

在上一章节从缓存中获取单例 进行了简单的分析,如果缓存中没有已经加载的bean 就得从头开始bean的加载过程了,而如下方法实现了bean的加载过程。

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {    Assert.notNull(beanName, "Bean name must not be null")

 代码及其相关注释:

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		// 全局变量需要同步
		synchronized (this.singletonObjects) {
			// 先检查对应的bean是否加载过,因为单例模式 就是复用以创建bean
			Object singletonObject = this.singletonObjects.get(beanName);
			// 如果为空才可以 进行singleton 的bean的初始化
			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 + "'");
				}
				// 循环依赖判断
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					// 初始化bean
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						throw ex;
					}
				}
				catch (BeanCreationException ex) {
					if (recordSuppressedExceptions) {
						for (Exception suppressedException : this.suppressedExceptions) {
							ex.addRelatedCause(suppressedException);
						}
					}
					throw ex;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					// 加入缓存
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

说明: 

  上述代码并没有做创建bean的操作,而是为创建bean做一些准备。

  step1: 检查缓存是否已经加载过

  step2:若没有加载,则记录beanName的正在加载状态。

  step3: 加载单例前记录加载状态。

 其中 beforeSingletonCreation 是记录加载状态,将正在加载的beanName 缓存在singletonsCurrentlyInCreation中。

 step4: 通过ObjectFactory 的getObject 实例化bean

step5:   后置处理 afterSingletonCreation 

    其中afterSingletonCreation 就是当bean 加载结束后,移除缓冲区对该bean的正在加载到状态记录。

step6:将该bean 缓存,同时移除一些相关辅助记录。

 

  接下来看一个核心代码块:

	sharedInstance = getSingleton( beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						} catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							// 从单例缓存中移除
							destroySingleton(beanName);
							throw ex;
						}
					});

     在getSingleton的有一个回调的函数,crateBean也就是getSingleton中的ObjectFactory。真正创建bean的操作其实就是这个createBean方法。

 接下来 来简单分析createBean

 

@Override
	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;
		// 锁定class ,根据class属性 或者根据className 来解析class
		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);
		}

		try {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

步骤说明:

  step1 : 根据class 设置的属性或者className 来解析class

  step2: 对override 属性进行验证和标记,(解决lookup-method和replaceMethod)

 step3 :resolveBeforeInstantiation,解析bean是否在初始化前的短路操作。

step4 :创建bean。

 

 

 

 

 

 

   

 

 

相关标签: Spring Bean创建