聊聊springBean的生命周期

在之前的篇幅中已经介绍过SpringIOC的一些细节,包括IOC的启动流程以及对应的源码解析过程。今天就SpringBean生命周期的事情好好的在聊一聊。

开始之前,给大家截了一个图,是BeanFactory接口中的一段注释:
在这里插入图片描述
其实从上面这段注释已经表达的很清楚了,大佬们已经把bean生命周期的流程已经列出来了。所以从这里我们就能够引申出另外一副构图:
在这里插入图片描述
在IOC详解的篇幅已经介绍了IOC的启动流程,如果还没有对整体流程没有概念的可以先去看看那篇,这里我们就直接进入整体。

下面我们就上图所示进行代码跟踪:

  1. bean的实例化

AbstractAutowireCapableBeanFactory.doCreateBean方法:
在这里插入图片描述
2.设置属性值
上述同类同方法:
在这里插入图片描述
在这里的populateBean方法主要是填充属性值的,如果是引用类型,可能会存在循环依赖问题,这个问题我会单独抽取出来作为一个篇幅来讲。

3.执行Aware方法。
我们先来了解下什么是Aware接口,他们都做了什么事情? spring中提供了很多的XXXAware接口,例如BeanNameAware、BeanFactoryAware、ApplicationContextAware等,这些接口可以让你IOC启动的过程中做一些事情,比如在实现BeanNameAware接口时,你可以获取beanName来做一些事情:
在这里插入图片描述
在bean生命周期中的Aware接口的执行是在2图中的initializeBean方法,进入到该方法中:
在这里插入图片描述
在这里插入图片描述
从上图中可以看出这里执行了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware三个Aware接口。

4.beanPostProcessor接口的before方法。

在spring中,有一个BeanPostProcessor接口,对应的还有一个BeanFactoryPostProcessor,他们分别是bean后置处理器、bean工厂后置处理器,也叫增强器,就是对bean或者beanFactory的增强处理。这里的bean后置处理器BeanPostProcessor接口有两个方法

	/**
	* 从方法名就可以知道在初始化之前的方法增强
	*说白了就是在初始化完事了在调用该方法。
	*/
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
	
	/**
	*在初始化之后的方法增强。
	*在初始化之后在调用该方法。
	*/
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

那么bean何时调用的beanPostProcessor的呢?
在3图中有一个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 {
		/**
		 * 执行是否实现了 XXAware接口的方法
		 */
		invokeAwareMethods(beanName, bean);
	}

	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
		/**
		 * 后置处理器的 before方法
		 */
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}

	try {
		/**
		 * 执行 InitializingBean接口方法 、 init-Method方法
		 */
		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;
    }

进入applyBeanPostProcessorsBeforeInitialization方法:

	@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	/**
	 * getBeanPostProcessors拿到所有已经注册了的 beanPostProcessor循环执行
	 */
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		Object current = processor.postProcessBeforeInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
    }

	public List<BeanPostProcessor> getBeanPostProcessors() {
		return this.beanPostProcessors;
	}

这里调用了getBeanPostProcessors()方法拿到了所有的beanPostProcessor然后循环调用执行。而且从getBeanPostProcessors方法内可以看出是直接返回了一个beanPostProcessors变量(它是个List集合),也就是说再此之前就已经add到list集合了,那么什么时候add到集合中的呢,在详解IOC的流程的篇幅中,在refresh()方法中已经详细的介绍了BeanPostProcessor的注册流程,这里就不过多赘述了,所这里自然而然的就从集合中拿出遍历执行了。

  1. 执行初始化方法。

在上述初始化方法中在执行bean的后置处理器的before方法之后的invokeInitMethod()方法:
在这里插入图片描述

	protected void invokeInitMethods(String beanName, Object bean, 	@Nullable RootBeanDefinition mbd)
		throws Throwable {

	/**
	 * 判断是否实现了 InitializingBean 接口
	 * 如果是则实行 InitializingBean接口的afterPropertiesSet方法。
	 */
	boolean isInitializingBean = (bean instanceof InitializingBean);
	if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
		if (logger.isTraceEnabled()) {
			logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
		}
		if (System.getSecurityManager() != null) {
			try {
				AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
					((InitializingBean) bean).afterPropertiesSet();
					return null;
				}, getAccessControlContext());
			}
			catch (PrivilegedActionException pae) {
				throw pae.getException();
			}
		}
		else {
			((InitializingBean) bean).afterPropertiesSet();
		}
	}

	/**
	 * 判断是否有 自定义的 初始化方法
	 * 这里就是我们在xml配置bean的时候,有一个init-Method属性,这里就是处理这个属性方法调用的。
	 */
	if (mbd != null && bean.getClass() != NullBean.class) {
		String initMethodName = mbd.getInitMethodName();
		if (StringUtils.hasLength(initMethodName) &&
				!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
				!mbd.isExternallyManagedInitMethod(initMethodName)) {
			invokeCustomInitMethod(beanName, bean, mbd);
		}
	}
	}
  1. 执行后置处理器的after方法。
    在上述初始化完成之后,进入到后置处理器的处理执行

在这里插入图片描述

	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		/**
		 * 同样获取到BeanPostProcessor,然后遍历执行 postProcessAfterInitialization方法
		 */
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

这里获取bea后置处理器的方法getBeanPostProcessors原理同上述分析的before方法的时候是一样的。

  1. 注册bean销毁策略
    同样是在AbstractAutowireCapableBeanFactory.doCreateBean方法中:
    在这里插入图片描述
    这里当你实现了DisposableBean接口或者有配置 destory-method属性,就会注册方法销毁策略。完成这一步就返回一个完整的springBean对象进入到单例池(或者说是一级缓存)中。

上述过程就是整个bean生命周期的过程,其实也是按照首图去一步步跟踪的,只不过细节需要自己去手动过一遍,这样会多springbean生命周期有一个更好的理解。

到这里可能有些小伙伴会对首图中的一开始的好多Aware接口有一些疑问,图中介绍了好多的Aware接口,为什么在上述介绍中就只有三种Aware接口,其他接口的执行在哪?

其实它们是通过beanPostProcessor实现调用了其他的一些Aware接口,这个beanPostProcessor是ApplicationContextAwareProcessor

它会在bean初始化之前调用,也就是before方法:
在这里插入图片描述

/**
	 * 判断是否实现了下列  Aware接口, 如果是则执行响应的方法。
	 * 这些Aware接口  是通过bean的后置处理器方式来实现调用的。
	 * @param bean
	 */
	private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof EnvironmentAware) {
				((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
			}
			if (bean instanceof EmbeddedValueResolverAware) {
				((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
			}
			if (bean instanceof ResourceLoaderAware) {
				((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
			}
			if (bean instanceof ApplicationEventPublisherAware) {
				((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
			}
			if (bean instanceof MessageSourceAware) {
				((MessageSourceAware) bean).setMessageSource(this.applicationContext);
			}
			if (bean instanceof ApplicationContextAware) {
				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
			}
		}
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值