spring源码干货分享-对象创建详细解析(set注入和初始化)

博客 分享
0 137
张三
张三 2022-03-15 18:56:42
悬赏:0 积分 收藏

spring源码干货分享-对象创建详细解析(set注入和初始化)

记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新。欢迎大家指正!

环境: spring5.X + idea

建议:学习过程中要开着源码一步一步过

Spring根据BeanDefinition创建单例对象

  1. DefaultSingletonBeanRegistergetSingleton((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);已经创建好的对象初始化之后再次加工。

最后

感谢您的阅读,有什么意见和问题欢迎评论区留言!书写不易!
觉得文章对你有帮助记得给我点个赞,欢迎大家关注和转发文章!

posted @ 2022-03-15 17:02 磊-01 阅读(1) 评论(0) 编辑 收藏 举报
回帖
    张三

    张三 (王者 段位)

    821 积分 (2)粉丝 (41)源码

     

    温馨提示

    亦奇源码

    最新会员