天天看點

spring源碼幹貨分享-對象建立詳細解析(set注入和初始化)

作者:馬士兵馬小小

記錄并分享一下本人學習spring源碼的過程,有什麼問題或者補充會持續更新。歡迎大家指正!

環境: spring5.X + idea           

建議:學習過程中要開着源碼一步一步過

Spring根據BeanDefinition建立單例對象

  1. DefaultSingletonBeanRegister 中getSingleton((String beanName, ObjectFactory<?> singletonFactory))
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, ...);
	}
	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) {
	  // 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;
  }
}           

解析:

  1. getSingleton 方法中還是先要在單例池中擷取将要被建立的對象是不是存在,不存在了才去建立。this.singletonObjects.get(beanName); 如果不存在Spring還會效驗一下是不是正在被銷毀,是則抛異常。this.singletonsCurrentlyInDestruction
  2. 一系列效驗完成後開始正式建立對象的第一步 beforeSingletonCreation(beanName);

    建立對象前要滿足倆個條件 inCreationCheckExclusions && singletonsCurrentlyInCreation.add(beanName) ,目前這個Bean沒有被排除,并且這個bean正在建立中。

  3. 通過 singletonFactory.getObject(); 回調createBean(beanName, mbd, args);

    建立對象時先擷取對應的BeanClass(通過反射建立對象),調用doCreateBean(beanName, mbdToUse, args);,這個方法中才是正兒八經的執行個體化對象

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  	throws BeanCreationException {
  // Instantiate the bean.
  BeanWrapper instanceWrapper = null;
  //....
  if (instanceWrapper == null) {
  	instanceWrapper = createBeanInstance(beanName, mbd, args);
  }
  Object bean = instanceWrapper.getWrappedInstance();
  Class<?> beanType = instanceWrapper.getWrappedClass();
  if (beanType != NullBean.class) {
  	mbd.resolvedTargetType = beanType;
  }
  //.............
  // Initialize the bean instance.
  Object exposedObject = bean;
  try {
  	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);
  	if (earlySingletonReference != null) {
  		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);
  				}
  			}
  			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 " +
  						"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
  			}
  		}
  	}
  }
   // Register bean as disposable.
  try {
  	registerDisposableBeanIfNecessary(beanName, bean, mbd);
  }
  catch (BeanDefinitionValidationException ex) {
  	throw new BeanCreationException(
  			mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
  }
  return exposedObject;
}           

doCreateBean解析:

A. 建立對象:createBeanInstance(beanName, mbd, args);

  1. 通過工廠方法建立對象
if (mbd.getFactoryMethodName() != null) {
      return instantiateUsingFactoryMethod(beanName, mbd, args);
  }           
  1. 通過預設的無參構造建立對象
instantiateBean(beanName, mbd);           

B. 填充屬性:populateBean(beanName, mbd, instanceWrapper);也是就是Set注入(構造注入已經在建立對象時執行了,自動注入可以忽略)

  1. 注解屬性指派
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;
			}
		}
	}           

解析:通過注解對屬性填充使用了AutowiredAnnotationBeanPostProcessor實作所有操作,在postProcessProperties(pvs, bw.getWrappedInstance(), beanName);方法中真正實作。

  1. 标簽方式屬性指派
if (pvs != null) {
    applyPropertyValues(beanName, mbd, bw, pvs);
  }           

解析:從RootBeanDefinition中擷取屬性的List封裝到PropertyValues中。

周遊ProperValues 把每個屬性的值進行類型轉換,最後再給bw設定得到的屬性值。-> BeanWrapper.setProperValues(new MutablePropertyValues(deepCopy))。

自定義類型會通過beanFactory.getBean() 擷取對應的對象,再走一遍doGetBean() -> createBean() -> doCreateBean()...

(JDK的類型會先封裝TypeStringValues。自定義的類型會封裝RuntimeBeanReference)

C. 初始化對象:initializeBean(beanName, exposedObject, mbd);

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
	if (System.getSecurityManager() != null) {
		.......
	}
	else {
		invokeAwareMethods(beanName, bean);
	}
	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}
	try {
		invokeInitMethods(beanName, wrappedBean, mbd);
	}
	catch (Throwable ex) {
		......
	}
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}
	return wrappedBean;
}           

解析:初始化分幾個功能

1. Aware -> invokeAwareMethods(String beanName, Object bean)。spring提供的幫助我們擷取Spring容器中對應的元件的相關資訊。

2. BeanPostProcessorsBefore -> applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);已經建立好的對象初始化之前再次加工。

3. 初始化 -> invokeInitMethods(beanName, wrappedBean, mbd);包含了接口初始化((InitializingBean) bean).afterPropertiesSet();和自定義方法初始化invokeCustomInitMethod(beanName, bean, mbd);

4. BeanPostProcessorsAfter -> applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);已經建立好的對象初始化之後再次加工。

最後

感謝您的閱讀,有什麼意見和問題歡迎評論區留言!書寫不易!

覺得文章對你有幫助記得給我點個贊,歡迎大家關注和轉發文章!

繼續閱讀