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

    最后

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

  • 相关阅读:
    Anaconda安装和配置
    详解Volatile关键字
    FPGA硬件工程师Verilog面试题(三)
    二进制安装k8s高可用部署
    通过插件去除Kotlin混淆去除 @Metadata标记
    OpenCascade模型导入与导出及Shap的读写
    strlen函数详解
    Android R给自家UA工具挖坑
    【Python】记录一次 Linux + Python + RocketMQ 辛酸历程
    QT 编程,StandardDialog、 QFileDialog
  • 原文地址:https://www.cnblogs.com/w001/p/16009244.html