Spring Bean的生命周期

Spring Bean的生命周期

请添加图片描述

综上为Spring的生命周期,主要生命周期为标颜色的部分,总共分四步。

  • 实例化bean(createBeanInstance)
  • 属性填充(populateBean)
  • 初始化bean(initializeBean)
  • 销毁

以下从源码阶段对Spring的生命周期进行分析

上面主要的代码实现都在doCreate()方法中。可以看到,在当前方法中有Spring Bean生命周期的三个步骤如下

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

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (instanceWrapper == null) {
            //1、实例化bean
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
            //2、属性填充
			populateBean(beanName, mbd, instanceWrapper);
            //3、初始化bean
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		
	

关于每个阶段的扩展点将会在下面的不同阶段进行穿插引入解读

一、实例化Bean

1、实例化Bean

对于BeanFactory容器,当客户向容器请求一个未初始化的Bean,或者初始化Bean的时候需要注入另外一个尚未初始化的依赖时,容器就会调用createBean方法。

对于ApplicationContext容器,当容器启动后,便会实例化所有的bean.

实例化对象被包含在BeanWrapper对象中,BeanWrapper提供了设置对象属性的接口,从而避免了使用反射机制设置属性。

啥是BeanWrapper?

​ BeanWrapper是对Bean的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装bean的属性描述器,由于BeanWrapper接口是PropertyAccessor的子接口,因此其也可以设置以及访问被包装对象的属性值。BeanWrapper大部分情况下是在spring ioc内部进行使用,通过BeanWrapper,spring ioc容器可以用统一的方式来访问bean的属性

实例化bean之后会得到一个BeanWrapper对象

2、实例化的前置操作和后置操作

先了解下InstantiationAwareBeanPostProcessor是个啥?

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
	//实例化之前的回调
	@Nullable
	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}
	//实例化之后但在显式属性设置或自动装配发生之前的回调
	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true;
	}
    ...

BeanPostProcessor的子接口,它添加一个实例化之前的回调,以及实例化之后但在显式属性设置或自动装配发生之前的回调

那么在实例化bean的过程中是如何体现前置调用和后置调用的?

InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {
    //实例化之前的回调,这个方法内部体现了
     Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}   
    try {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}

InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
	 //实例化之后的回调
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						return;
					}
				}
			}
		}
///属性赋值操作。。。

二、属性填充

1、属性填充

属性填充的方法为populateBean()

主要目的是将RootBeanDefinition的值填充给BeanWrapper对象的。

这里面包括了根据类型填充对象和根据name填充对象,具体可以看下文章:https://blog.csdn.net/qq_35712465/article/details/120086429

2、检查Aware相关接口并设置相关依赖

Spring会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给bean

关于Aware的了解可以去看下文章:https://blog.csdn.net/qq_35712465/article/details/120086429

三、初始化阶段

1、初始化bean

在bean实例化之前来执行用户自定义的方法,这种指定有两种方式可以进行指定

  1. 在配置文件中配置init-method属性
  2. 实现InitializingBean 接口,来自定义afterPropertiesSet()方法

想了解更多初始化bean 相关的可以看下文章:https://blog.csdn.net/qq_35712465/article/details/120086429

2、初始化的前置操作和后置操作

这里的前置操作和后置操作在实例化代码中的体现为:

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
	

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
            //初始化前的前置操作
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
            //初始化
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		
		if (mbd == null || !mbd.isSynthetic()) {
            //初始化后的后置操作
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

这里的是实例化操作是基于BeanPostProcessor接口的,注意,与上面有点区别,上面是使用了BeanPostProcessor的子接口

四、销毁

  • 调用DiposibleBean的Destory()方法
  • destory-method指定函数
  • @PreDestroy

这两种方法并不是真正销毁bean的方法,它只是在销毁bean之前执行的你自定义的一个逻辑而已。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值