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

15 篇文章 0 订阅

Spring作为当前Java最流行、最强大的轻量级框架。深入的了解Spring Bean的生命周期是非常必要的。我们通常把ApplicationContext作为Spring容器。所以,我们讲的也是ApplicationContext容器中Bean的生命周期。

        在Spring中,其实有一个类完完整整的描述了Spring Bean的生命周期。让我们来看这个类

 一:Spring Bean的生命周期流程图。

二:Spring Bean的生命周期主要有这四个阶段:


        1. 实例化   createBeanInstance

        2. 属性赋值   populateBean

        3. 初始化    initializeBean

        4. 销毁     destroyBean

        实例化 -> 属性赋值 -> 初始化 -> 销毁

      整个Spring Bean的生命周期逻辑都在doCreateBean()方法中。逻辑清晰,按顺序调用。

三:下面看源码:

       1. 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) {
			/**
		     * 创建 bean 实例,并将实例包裹在 BeanWrapper 实现类对象中返回。
		     * createBeanInstance中包含三种创建 bean 实例的方式:
		     *   1. 通过工厂方法创建 bean 实例
		     *   2. 通过构造方法自动注入(autowire by constructor)的方式创建 bean 实例
		     *   3. 通过无参构造方法方法创建 bean 实例
		     *
		     * 若 bean 的配置信息中配置了 lookup-method 和 replace-method,则会使用 CGLIB 增强 bean 实例。
		     */
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		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 {
					//BeanPostProcessor的运用2:扫描注解
					//扫描类的属性、方法上是否有@PostConstruct@PreDestroy @Resource@Autowired @Value注解
					//CommonAnnotationBeanPostProcessor -> @PostConstruct @PreDestroy @Resource
		            //AutowiredAnnotationBeanPostProcessor -> @Autowired @Value
					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.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			//提前暴露bean对象,放入三级缓存
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			//初始化Bean对象:属性依赖注入
			populateBean(beanName, mbd, instanceWrapper);
			//初始化bean对象:调用初始化方法等...
			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.");
					}
				}
			}
		}

		try {
			// Register bean as disposable.
			//注册销毁方法:最终会被ContextLoaderListener的contextDestroyed方法调用
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

        2.实例化整个流程

         2.1)调用createBeanInstance方法通过BeanDefinition信息实例化Bean对象:                 

          2.2)主要用来收集构造器信息,用于反射实例化:

         2.3)继续往下看:

         2.4)真正的反射实例化对象,先开启权限可以访问,在调用ctor.newInstance(args)方法创建对象。

       3.属性赋值整个流程

         3.1)调用populateBean完成属性赋值(属性的依赖注入):                

         3.2)调用InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法完成属性赋值,这里主要看AutowiredAnnotationBeanPostProcessor实现类:  

        3.3)通过属性、方法上有@Autowired@Resource@Value注解的进入依赖注入:

         3.4)属性的依赖注入:

                首先拿到属性:Field field = (Field) this.member,

                然后从SpringIOC容器中获取属性的值:value = beanFactory.resolveDependency();

                最后完成属性的赋值:field.set(bean, value)

        3.5)方法的依赖注入:

                首先拿到方法:Method method = (Method) this.member;

                然后完成方法的参数封装:

                最后完成方法的调用:method.invoke(bean, arguments);

       4.初始化整个流程

         4.1)初始化入口:

         4.2)完成初始化功能:

                完成Aware接口的调用;                        

                完成BeanPostProcessor.postProcessBeforeInitialization方法调用;

                完成初始化方法的调用;完成自定义初始化方法的调用;

                完成BeanPostProcessor.postProcessAfterInitialization方法调用;

          5.销毁整个流程

                Bean的销毁整个流程比较复杂:

                5.1)注册销毁方法;

                5.2)调用注册的销毁方法。

             什么时候销毁?   由谁调用销毁方法?是我们的SpringIOC容器吗?

          首先肯定不是我们的SpringIOC容器调用销毁。也只有我们的Servlet容器关闭后需要销毁;也只有servlet容器有权利调用销毁方法。               

         5.3)看一下注册销毁:注册销毁方法是在我们的Bean创建完成后完成注册的;

                5.3.1) 注册销毁的入口;  

                 5.3.2)把销毁方法包装成了DisposableBeanAdapter;

                5.3.3)包装后的对象放入属性disposableBeans容器中。

         5.4)看一下调用销毁方法:调用销毁方法是我们的servlet容器;

         5.4.1)servlet容器关闭后调用spring容器销毁;

         5.4.2)最终会调到这个方法;完成属性的移除、销毁方法的调用。

到此.   Spring Bean的生命周期介绍结束,请看下一章.

            编译好的Spring源码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java的艺术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值