likes
comments
collection
share

浅谈spring bean的生命周期

作者站长头像
站长
· 阅读数 18

生命周期,简单理解就是事物从开始出现到最终消亡的一段时间。spring bean的生命周期就是从spring创建bean,到最终spring将bean销毁的一个过程(或一段时间),而我们上篇谈到的spring bean的初始化方法和销毁方法,都会在bean的生命周期内得到调用。简单来说,spring容器中的bean会经历如下过程:

创建bean实例-->创建完成,正常使用-->spring销毁bean

接下来我们就基于spring 5.3.20版本的代码对上述过程详细分析下。

1、代码跟踪

spring容器启动的时候,会调用org.springframework.context.support.AbstractApplicationContext#refresh。其中refresh方法实现如下:

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// 本篇的关注点,实例化所有非懒加载的单例bean
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
				contextRefresh.end();
			}
		}
	}

本次我们关注其中的finishBeanFactoryInitialization 方法,看下方法的最后一行代码:

       // Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();

跟踪preInstantiateSingletons方法,最终会经历如下的流程来创建bean。

1.1、AbstractBeanFactory#getBean(java.lang.String)
1.2、AbstractBeanFactory#doGetBean
1.3、AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
1.4、AbstractAutowireCapableBeanFactory#doCreateBean

最终由步骤1.4完成bean的创建。

2、创建bean

分析1.4步骤的doCreateBean方法,我们可以得出如下bean的创建过程。

创建bean实例-->填充bean属性-->初始化bean

2.1、创建bean实例

本过程的实现对应createBeanInstance方法,该方法根据bean定义信息,采取合适的策略(指定的工厂方法、构造器注入或使用无参构造器)创建bean对象。

2.2、填充bean属性

本过程的实现对应populateBean方法,完成bean的属性的赋值操作。

2.3、初始化bean

本过程的实现对应initializeBean方法,initializeBean方法实现如下:

	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
            //调用各种aware接口方法
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
            // 调用所有的BeanPostProcessor对象的postProcessBeforeInitialization方法
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
            // 调用bean的初始化方法
			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()) {
            // 调用所有的BeanPostProcessor的postProcessAfterInitialization方法
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

通过分析以上代码,我们可以得出初始化过程依次所做的各种操作。

(1)调用各种aware接口方法

a.如果bean是BeanNameAware的实例,则调用它的setBeanName方法
b.如果bean是BeanClassLoaderAware的实例,则调用它的setBeanClassLoader方法
c.如果bean是BeanFactoryAware的实例,则调用它的setBeanFactory方法。

(2)调用所有的BeanPostProcessor对象的postProcessBeforeInitialization方法

​ 获取spring容器中所有的BeanPostProcessor对象,循环执行各个beanPostProcessor的postProcessBeforeInitialization方法,如果出现postProcessBeforeInitialization返回的对象为null,则终止循环,返回上一个postProcessBeforeInitialization方法返回的对象,然后进入第(3)步。

(3)调用bean的初始化方法

a.如果bean是InitializingBean的实例,则调用它的afterPropertiesSet方法
b.如果bean有自定义的初始化方法,则通过反射执行它的自定义初始化方法。

(4)调用所有的BeanPostProcessor的postProcessAfterInitialization方法

​ 获取spring容器中所有的BeanPostProcessor对象,循环执行各个beanPostProcessor的postProcessAfterInitialization方法,如果出现postProcessAfterInitialization返回的对象为null,则终止循环,直接返回上一个postProcessAfterInitialization方法返回的对象。

3、正常使用bean

经过了bean的创建过程,此时就可以正常使用spring容器中的bean了

4、销毁bean

当spring容器被销毁的时候,容器中的bean也随之销毁。而容器被销毁的时候,又会针对各个bean依次作出如下操作:

(1)如果bean中有标记@PreDestroy的方法,则执行该方法
(2)如果bean实现了DisposableBean接口,则调用它的destroy方法
(3)如果Bean有自定义的销毁方法,则执行该方法

结束语

本文先分享到这里,觉得有收获的朋友,可以点击“关注”,或者进行分享或收藏,有疑惑的也可以来私聊评论,我会及时进行回复~