6、Spring之Bean生命周期~创建Bean(2)

发布于:2024-06-12 ⋅ 阅读:(56) ⋅ 点赞:(0)

6、Spring之Bean生命周期~创建Bean

创建Bean

通过《Spring之Bean生命周期~创建Bean(1)》,我们知道,在Bean创建直接会先确保BeanClass已经被加载,然后直接实例化前操作,如果实例化前有返回值直接跳过实例化、依赖注入、初始化前步骤,进入初始化,如果实例化前没有返回值,我调用doCreateBean()方法,废话不多说,上代码:

/**
 * Actually create the specified bean. Pre-creation processing has already happened
 * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
 * <p>Differentiates between default bean instantiation, use of a
 * factory method, and autowiring a constructor.
 *
 * @param beanName the name of the bean
 * @param mbd      the merged bean definition for the bean
 * @param args     explicit arguments to use for constructor or factory method invocation
 * @return a new instance of the bean
 * @throws BeanCreationException if the bean could not be created
 * @see #instantiateBean
 * @see #instantiateUsingFactoryMethod
 * @see #autowireConstructor
 */
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {

	// 实例化bean
	// Instantiate the bean.
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		// 有可能在本Bean创建之前,就有其他Bean把当前Bean给创建出来了(比如依赖注入过程中)
		// factoryBeanObjectCache:存的是beanName对应的FactoryBean.getObject()所返回的对象
		// factoryBeanInstanceCache:存的是beanName对应的FactoryBean实例对象
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		// 创建Bean实例
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	Object bean = instanceWrapper.getWrappedInstance();
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}

	// 后置处理合并后的BeanDefinition
	// Allow post-processors to modify the merged bean definition.
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			} catch (Throwable ex) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Post-processing of merged bean definition failed", ex);
			}
			mbd.postProcessed = true;
		}
	}

	// 为了解决循环依赖提前缓存单例创建工厂
	// Eagerly cache singletons to be able to resolve circular references
	// even when triggered by lifecycle interfaces like BeanFactoryAware.
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		if (logger.isTraceEnabled()) {
			logger.trace("Eagerly caching bean '" + beanName +
					"' to allow for resolving potential circular references");
		}
		// 循环依赖-添加到三级缓存
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	}

	// 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)) {
				// beanName被哪些bean依赖了,现在发现beanName所对应的bean对象发生了改变,那么则会报错
				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;
}

通过上述代码,我们可以看到:

  1. 判断BeanDefinition是否是单例的,如果是单例的会从factoryBeanInstanceCache缓存中清除缓存;
  2. 缓存中不存在会调用createBeanInstance()方法进行实例化;实例化 Bean,有四种方式:工厂方法,Supplier 回调、有参构造函数自动注入、默认构造函数注入,详情请移步《Spring之Bean生命周期~推断构造方法
  3. 实例化完成之后,会调用applyMergedBeanDefinitionPostProcessors()方法进行BeanDefinition的后置处理。当一个bean实现了MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法,实例化后会调用,可以给BeanDefinition设置初始化方法、通过BeanDefinition给属性赋值;(Spring源码中,AutowiredAnnotationBeanPostProcessor类的中postProcessMergedBeanDefinition方法寻找@Value和@Autoword的注入点,CommonAnnotationBeanPostProcessor类中的postProcessMergedBeanDefinition方法寻找@Resource的注入点)
  4. 调用populateBean()方法完成属性填充,也是我们常说的依赖注入,详情请移步至《Spring之Bean生命周期~依赖注入
  5. 属性填充完成之后,会调用initializeBean()方法进行初始化操作;详情请移步至《Spring之Bean生命周期~初始化
  6. 在doCreateBean()方法的最后一步会调用registerDisposableBeanIfNecessary(),标记Bean对象是否设置销毁回调方法,如果有回进行记录;详情请移步至《Spring之Bean生命周期~销毁

网站公告

今日签到

点亮在社区的每一天
去签到