Spring源码分析-Bean生命周期createBean

Spring源码分析系列

Spring源码分析-启动流程浅析
Spring源码分析-BeanDefinition
Spring源码分析-Bean管理查找与注册(1)
Spring源码分析-Bean管理查找与注册(2)
Spring源码分析-Bean管理循环依赖和三级缓存
Spring源码分析-Bean生命周期概述
Spring源码分析-Bean生命周期createBean



前言

bean的生命周期状态虽然比较多,但是通过梳理代码其实也不是那么复杂。再次回顾bean的生命周期:
实例化 -->属性赋值–> bean后置处理器的before方法 --> 属性后置处理afterPropertiesSet --> bean初始化过程 --> bean后置处理器的after方法 --> 对象应用 --> bean销毁过程 --> gc回收


一、bean创建流程

在这里插入图片描述
通过流程图来,bean的创建流程也不太复杂啊😃😃

二、doCreateBean

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {

	// Instantiate the bean.
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		instanceWrapper = createBeanInstance(beanName, mbd, args); // 创建bean实例
	}
	Object bean = instanceWrapper.getWrappedInstance();
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}

	// 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");
		}
		//先放到 三级缓存 中 这个地方是lambda表达
		//三级缓存
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

		/** add by xuxb 测试代码 需要将缓存声明private 改成 protected */
		//Object targetBean = getEarlyBeanReference(beanName, mbd, bean);
		//earlySingletonObjects.put(beanName, targetBean); //添加二级缓存
		//registeredSingletons.add(beanName);
	}

	// Initialize the bean instance.
	Object exposedObject = bean;
	try {
		//属性赋值
		populateBean(beanName, mbd, instanceWrapper);
		//执行后置处理器BeanPostProcessor,  如果动态代理场景 则返回的是动态代理对象
		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) {
		// 这里是false,只查询一级缓存,二级缓存,不查三级缓存
		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;
}

三、总结

主要是流程图,代码逻辑不复杂,这里不再介绍,大家可按照流程图翻看源码。

Spring bean的生命周期可以分为以下阶段: 1. 实例化:通过反射或工厂方法创建对象实例。 2. 属性注入:将对象的属性值设置到bean实例中。 3. Aware回调:调用实现了Aware接口的回调方法,例如BeanNameAware、BeanFactoryAware等。 4. 初始化前回调:调用实现了InitializingBean接口或使用@Bean(initMethod="methodName")指定的初始化方法。 5. 初始化后回调:调用实现了BeanPostProcessor接口的postProcessBeforeInitialization和postProcessAfterInitialization方法。 6. 销毁前回调:调用实现了DisposableBean接口或使用@Bean(destroyMethod="methodName")指定的销毁方法。 7. 销毁后回调:调用实现了BeanPostProcessor接口的postProcessBeforeDestruction方法。 下面我们来分析一下Spring源码bean的生命周期实现过程。 首先,Spring使用BeanFactory在需要时创建bean实例。BeanFactory是一个接口,它定义了获取和管理bean的方法。在使用Spring时,通常使用其子接口ApplicationContext。 BeanFactory的实现类DefaultListableBeanFactory中,当调用getBean方法时,会根据传入的bean名称从缓存中获取bean实例,如果缓存中没有,则会调用createBean方法创建一个新的实例。 createBean方法中,首先会进行实例化,即通过反射或工厂方法创建对象实例。然后,会进行属性注入,将对象的属性值设置到bean实例中。 接下来,会调用实现了Aware接口的回调方法,例如BeanNameAware、BeanFactoryAware等。然后,会调用实现了InitializingBean接口或使用@Bean(initMethod="methodName")指定的初始化方法。 在调用初始化方法之前,会先调用实现了BeanPostProcessor接口的postProcessBeforeInitialization方法。在调用初始化方法之后,会调用实现了BeanPostProcessor接口的postProcessAfterInitialization方法。 在bean被销毁之前,会调用实现了DisposableBean接口或使用@Bean(destroyMethod="methodName")指定的销毁方法。在销毁方法之前,会先调用实现了BeanPostProcessor接口的postProcessBeforeDestruction方法。最后,销毁bean实例。 总结一下,Spring bean的生命周期主要是通过BeanFactory中的createBean方法实现的,包括实例化、属性注入、Aware回调、初始化前后回调、销毁前后回调等过程。其中,BeanPostProcessor接口的实现类可以在bean的初始化前后进行拦截和处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值