栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring源码(三)Spring Bean的生命周期

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring源码(三)Spring Bean的生命周期

了解专栏完整的内容,请点击跳转:
Spring framework专栏导航页


上一篇文章,我门已经了解了Spring容器初始化的过程。初始化过程中会将单例、非抽象的、非懒加载的Bean创建好并放进缓存中以供使用。Bean的生命周期也就是指创建、使用、销毁的全过程,下面就此展开。


流程图点击查看


Bean的生命周期

大白话概述一下Bean的创建:
我们知道对象(即Bean)的创建一般使用new或者反射的方式创建,Spring就是采用反射的方式来创建Bean。Spring Bean的创建包括了实例化、属性赋值、初始化,经过以上三步就能完成Bean的创建。

但Spring既然是框架,就要给使用者多提供一些拓展点,让用户扩展,所以在Bean的生命周期中,会有9个BeanPostProcessor以及一些可以拓展的接口。
这些后置处理器干嘛用的?说白了就是每个Bean创建时候都去遍历一下当前的后置处理器,看是否需要被处理一下。遍历的时机也是有好几处。
有了拓展点以外,还有一个棘手的问题就是Bean间循环依赖(A依赖B,B依赖A)的问题,以及循环依赖下AOP(需要创建代理对象,并把代理对象赋值给被依赖Bean)。为了解决这个问题,Spring是借助一、二、三级缓存和后置处理器来实现的,循环依赖的具体细节将在下一篇文章阐述。


实例化前
	try {
			
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			//判断容器中是否有InstantiationAwareBeanPostProcessors
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);

					// 一般情况下返回的都是null
					// 如果不为null说明生成了代理对象那么我们就调用
					if (bean != null) {
						
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

实例化
if (instanceWrapper == null) {
			// 实例化
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}

@Autowired预处理
try {
					// 第3个bean后置处理器
					// 进行后置处理 @AutoWired @Value的注解的预解析
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}

实例化后的Bean放三级缓存
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");
			}
			//把我们的早期对象包装成一个singletonFactory对象 该对象提供了一个getObject方法,
			// 该方法内部调用getEarlyBeanReference方法,该方法再去调后置处理器
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

填充属性
// 填充属性
populateBean(beanName, mbd, instanceWrapper);

初始化
// aware方法、初始化前、初始化、 初始化后
exposedObject = initializeBean(beanName, exposedObject, mbd);
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			// 执行aware方法
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			// 执行before处理器
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// 执行初始化方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			// 执行after方法
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
 
销毁 
@Override
	public void close() {
		synchronized (this.startupShutdownMonitor) {
			doClose();
			// If we registered a JVM shutdown hook, we don't need it anymore now:
			// We've already explicitly closed the context.
			if (this.shutdownHook != null) {
				try {
					Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
				}
				catch (IllegalStateException ex) {
					// ignore - VM is already shutting down
				}
			}
		}
	}
@PostConstruct

最后提一点。很多人觉得这个注解标记的方法,是在Bean初始化阶段的invokeInitMethods(beanName, wrappedBean, mbd);里边执行的,
其实是在初始化阶段的applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);执行的

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号