【Spring源码学习篇(二)】☀️从源码的角度梳理SpringBean的生命周期~✨

前言

⚡️ 本篇结合Spring源码简要的梳理了一下Spring的bean的生命周期,注释已经写在自己拉下来的Spring项目里面啦,如果感兴趣的小伙伴,可以从本人的 GitHub【Spring-Framework-Cocowwy 仓库里面下载源码观摩噢~

Spring源码相关系列文章:
⭐️ 【Spring源码学习篇(一)】☀️Spring5本地环境编译,超级实用!!✨

Bean的生命周期

⚡️ 在通过源码进行分析之前,先上代码和Demo,简要看看Bean的生命周期有关的几个接口的使用,先实操再上硬菜!🍜

Bean的生命周期简介

⚡️ 简简单单总结一下叭:一个JavaBean,从实例化然后经过属性赋值再到初始化完成最后再到销毁的过程,就是其生命周期,在一个bean经过这个生命周期的过程中,Spring提供了许多的可扩展点,用于我们对其进行扩展。类似于下图。
在这里插入图片描述

这几个接口你了解吗?

对于Bean的生命周期而言,Spring为其提供了如下几个重要的接口:
⚡️ InstantiationAwareBeanPostProcessor
⚡️ BeanPostProcessor
⚡️ XXXXXXAware
⭐️ 接下来本篇文章就针对这三个核心接口来展SpringBean的生命周期我们可以从下图来看SpringBean的生命过程中以上接口各自是在什么情况下执行的。
在这里插入图片描述
🌚图画的有点丑,见谅🌚
⭐️由上图可以知道,在 实例化 的前后,会分别执行 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation / postProcessAfterInstantiation 在初始化之前会执行一系列的 XXXAware接口 ,在执行完这些接口之后同时在 初始化 前后会执行BeanPostProcessor#postProcessBeforeInstantiation / postProcessAfterInstantiation ,最后再到Bean的销毁。到此Bean的生命周期中几个重要的可扩展的接口就已经走完。
⚡️ 细心的读者会发现InstantiationAwareBeanPostProcessor是继承自BeanPostProcessor的。

InstantiationAwareBeanPostProcessor

🌝 感知Bean实例化的处理器,继承自 BeanPostProcessor ,在bean实例化的前后执行

BeanPostProcessor

🌝 检查标记接口或使用代理包装 bean,在初始化的前后执行

XXXXAware

🌝 继承自 Aware 接口,bean对象继承该接口后,能够在初始化bean之前从该接口方法中拿到xxx的一些相关属性,并且执行该方法

挽起袖子,撸源码

前期准备工作

⚡️ 先放上调试的Demo
💥 Student

/**
 * @author Cocowwy
 * @create 2021-08-08-13:38
 */
public class Student implements BeanNameAware, EnvironmentAware {
	private String name;
	private String studentNo;
	private String sex;

	public Student() {}
	
	@Override
	public String toString() {
		return "Student{" +
				"name='" + name + '\'' +
				", studentNo='" + studentNo + '\'' +
				", sex='" + sex + '\'' +
				'}';
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		System.out.println("对name属性进行赋值");
		this.name = name;
	}

	public String getStudentNo() {
		return studentNo;
	}

	public void setStudentNo(String studentNo) {
		System.out.println("对studentNo属性进行赋值");
		this.studentNo = studentNo;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		System.out.println("对sex属性进行赋值");
		this.sex = sex;
	}

	@Override
	public void setBeanName(String name) {
		System.out.println("执行Student类的BeanNameAware接口方法");
	}

	@Override
	public void setEnvironment(Environment environment) {
		System.out.println("执行Student类的EnvironmentAware接口方法");
	}
}

💥 MyBeanPostProcessor

/**
 * @author Cocowwy
 * @create 2021-08-08-15:10
 */
public class MyBeanPostProcessor implements BeanPostProcessor, Ordered {

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println(beanName + "执行初始化之前的方法【BeanPostProcessor#postProcessBeforeInitialization】");
		// 从源码可以知道这里就算返回null  spring底层还是能够取到bean对象
		// AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
		return null;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println(beanName + "执行初始化之后的方法【BeanPostProcessor#postProcessAfterInitialization】");
		Student returnBean = (Student) bean;
		returnBean.setName("BeanPostProcessor#postProcessAfterInitialization");
		return returnBean;
	}

	// BeanPostProcessor 的执行顺序
	@Override
	public int getOrder() {
		return 0;
	}
}

💥 MyInstantiationAwareBeanPostProcessor

/**
 * @author Cocowwy
 * @create 2021-08-08-15:07
 */
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor , Ordered {
	/**
	 * 对象实例化之前调用,返回回值是Object类型
	 * 由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成对象的目标对象的实例(比如代理对象)。
	 * 如果该方法的返回值代替原本该生成的目标对象,
	 * 后续只有postProcessAfterInstantiation方法会调用,其他方法不调用;否则按照正常的流程走
	 * @param beanClass the class of the bean to be instantiated
	 * @param beanName the name of the bean
	 * @return
	 * @throws BeansException
	 */
	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		System.out.println(beanName + "执行实例化之前的方法【InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation】");
		return null;
	}

	/**
	 * 对象实例化之后调用,此时对象的属性值都是null。
	 * 返回值是决定要不要调用postProcessPropertyValues方法中的一个因素(因为还有一个因素是mbd.getDependencyCheck());
	 * 如果该方法返回false,并且不需要check,那么postProcessPropertyValues就会不执行;
	 * 如果返回true,postProcessPropertyValues就会被执行
	 * @param bean the bean instance created, with properties not having been set yet
	 * @param beanName the name of the bean
	 * @return
	 * @throws BeansException
	 */
	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		System.out.println(beanName + "执行实例化之后的方法【InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation】");
		return true;
	}

	@Override
	public int getOrder() {
		return 0;
	}
}

💥 spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:p="http://www.springframework.org/schema/p"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
	<bean id="student" class="bean.Student">
		<property name="name" value="Cocowwy"></property>
		<property name="sex" value="boy"></property>
		<property name="studentNo" value="PC66715"></property>
	</bean>
	<bean class="life.MyBeanPostProcessor"/>
	<bean class="life.MyInstantiationAwareBeanPostProcessor"/>

💥 Test

/**
 * @author Cocowwy
 * @create 2021-08-08-17:28
 */
public class Test {
	public static void main(String[] args) {
		System.out.println("=====================spring容器【create by:Cocowwy】==================================");
		ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
		Student student = (Student) context.getBean("student");
		System.out.println(student);
	}
}

InstantiationAwareBeanPostProcessor的执行时机

postProcessBeforeInstantiation

🍉 方法的执行入口:AbstractAutowireCapableBeanFactory#createBean

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

🍉 点击 resolveBeforeInstantiation 进去瞅瞅源码~

	/**
	 * 【应用实例化前的后处理器】
	 */
	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// 确保此时真正解析了 bean 类
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
				    // 执行 applyBeanPostProcessorsBeforeInstantiation 的时机
				    // student执行实例化之前的方法【InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation】
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

🍉 该方法在 Object beanInstance = doCreateBean(beanName, mbdToUse, args) 之前执行,即bean初始化之前执行

postProcessAfterInstantiation

🍉 该方法是在实例化之后执行,从上文 Object beanInstance = doCreateBean(beanName, mbdToUse, args) 接着往后走,在这个方法里完成了bean的初始化和实例化,故此我们先从这里点进去接着看源码~
进入到方法里面,看到我们的 populateBean(beanName, mbd, instanceWrapper) 方法,在这里完成属性的赋值。
接着从这里点进去,进入到我们的 populateBean 方法,
🍉 方法的执行入口:AbstractAutowireCapableBeanFactory#populateBean,接下来贴出该方法里执行postProcessAfterInstantiation的位置

		// InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation 
		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
		// state of the bean before properties are set. This can be used, for example,
		// to support styles of field injection.
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				// 执行 postProcessAfterInstantiation
				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}

🍉 由下图截屏可以得知,bean仅完成了实例化,但是未进行属性赋值(student全部为空)的操作,在该代码块的位置进行了实例化的后置处理器的postProcessAfterInstantiation操作
在这里插入图片描述

XXXXAware接口的执行时机

🍉 刚才从populateBean里面执行完了实例化的后置处理器,以及实例化后的属性赋值,接下来开始执行的是XXXXAware接口的调用了
🍉 坐标定位:AbstractAutowireCapableBeanFactory#doCreateBean

		try {
			//这里是拿的包装了这个bean的包装类BeanWrapper,在这里完成了对属性的赋值
			populateBean(beanName, mbd, instanceWrapper);
			
			// 初始化bean 这里执行了bean的Aware接口的方法
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		} catch (Throwable ex) {
			......
		}

🍉 接着我们点进initializeBean开始跟源码~
🍉 坐标定位:AbstractAutowireCapableBeanFactory#initializeBean

		// 当运行未知的Java程序的时候,该程序可能有恶意代码(删除系统文件、重启系统等),
		// 为了防止运行恶意代码对系统产生影响,需要对运行的代码的权限进行控制,这时候就要启用Java安全管理器。
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		} else {
			// 未启用安全管理器就执行这三个接口【BeanNameAware BeanClassLoaderAware BeanFactoryAware】
			// 执行Student类的BeanNameAware接口方法,获取到的beanName为:student
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			// 执行其余的Aware接口方法  在初始化之前执行bean的处理器
			// 执行如下接口处理【EnvironmentAware EmbeddedValueResolverAware  ResourceLoaderAware  ApplicationEventPublisherAware
			// MessageSourceAware  ApplicationContextAware ApplicationStartupAware】
			// student执行初始化之前的方法【BeanPostProcessor#postProcessBeforeInitialization】
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

🍉 虽然上面巴拉巴拉的一大堆,不过执行Aware接口地方的代码就两个部分,一个是 invokeAwareMethods(beanName, bean) 另外一个是 applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)

BeanNameAware / BeanClassLoaderAware / BeanFactoryAware

🍉 第一个部分
我们可以先点进去 invokeAwareMethods看看里面的内容

// 调用invoke方法
	private void invokeAwareMethods(String beanName, Object bean) {
		// 这一块用来debug的时候打印的哈~
		if (beanName.equals("student")) {
			System.out.println("执行【BeanNameAware接口】part:1======【AbstractAutowireCapableBeanFactory:invokeAwareMethods】");
		}
		
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				// 将beanName返回
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				// 拿到类加载器,如果不为空则返回该类加载器
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			if (bean instanceof BeanFactoryAware) {
				// 返回Bean工厂 ----》 AbstractAutowireCapableBeanFactory
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

🍉 可以看到,bean实现了Aware接口的BeanNameAwareBeanClassLoaderAwareBeanFactoryAware其中的接口的时候,会在这一步操作执行该接口的方法,同时拿到一系列bean相关的参数,就比如BeanNameAware,可以在这里拿到bean的name

EnvironmentAware / EmbeddedValueResolverAware / ResourceLoaderAware ApplicationEventPublisherAware / MessageSourceAware / ApplicationContextAware / ApplicationStartupAware

🍉 接着我们再来看看 第二个部分 applyBeanPostProcessorsBeforeInitialization方法

	@Override
	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {
		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			// 剩余的Aware接口在这里进行的解析 -》 ApplicationContextAwareProcessor#postProcessBeforeInitialization
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

🍉 当代码运行到 Object current = processor.postProcessBeforeInitialization(result, beanName) 的时候,执行的是 ApplicationContextAwareProcessor#postProcessBeforeInitialization 方法,接下来贴出这块的核心代码

	// 初始化前的处理
	@Override
	@Nullable
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// 执行其余的Aware接口 如果bean没实现这些接口就返回
		if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
				bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
				bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware ||
				bean instanceof ApplicationStartupAware)) {
			return bean;
		}
		
		......
		
		if (...) {......} else {
			// 执行aware接口的方法,这里得if打了个日志哈
			if (beanName.equals("student")) {System.out.println("执行【EnvironmentAware接口】part:2======【ApplicationContextAwareProcessor:invokeAwareInterfaces】");}
			// 实际执行第二部分的Aware接口
			invokeAwareInterfaces(bean);
		}
		......
	}

	private void invokeAwareInterfaces(Object bean) {
		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 ApplicationStartupAware) {
			((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
		}
		if (bean instanceof ApplicationContextAware) {
			((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
		}
	}

🍉 最终我们可以看到实际执行XXXAware接口的地方是invokeAwareInterfaces方法,在这里,给bean提供了扩展点,能够在赋值完初始化前获取到environment,applicationContext 等信息

BeanPostProcessor的执行时机

postProcessBeforeInitialization

🍉 如果你在debug源码的时候就会发现,在上文执行Aware接口的时候,代码是长这个鬼样的

		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			// 剩余的Aware接口在这里进行的解析 -》 ApplicationContextAwareProcessor#postProcessBeforeInitialization
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}

🍉 计算一下 getBeanPostProcessors() 的值就会发现,这里面有我们自己定义的 MyBeanPostProcessors ,也就是说,在执行完上面的Aware接口的随后(在一个for循环内),紧接着执行了我们的BeanPostProcessor#postProcessBeforeInitialization
在这里插入图片描述

postProcessAfterInstantiation

🍉 坐标定位:AbstractAutowireCapableBeanFactory#initializeBean

		if (mbd == null || !mbd.isSynthetic()) {
			// 执行其余的Aware接口方法  在初始化之前执行bean的处理器
			// 执行如下接口处理【EnvironmentAware EmbeddedValueResolverAware  ResourceLoaderAware  ApplicationEventPublisherAware
			// MessageSourceAware  ApplicationContextAware ApplicationStartupAware】
			// student执行初始化之前的方法【BeanPostProcessor#postProcessBeforeInitialization】
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// 初始化
			invokeInitMethods(beanName, wrappedBean, mbd);
		} catch (Throwable ex) {
			// ......
		}
		if (mbd == null || !mbd.isSynthetic()) {
			// 在初始化之前执行bean的处理器   student执行初始化之后的方法【BeanPostProcessor#postProcessAfterInitialization】
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

🍉 从上文可以知道,此时已经执行完aware接口以及postProcessBeforeInitialization,此时接着往下经过了Init初始化完毕之后,开始执行applyBeanPostProcessorsAfterInitialization方法,这里执行的就是我们的BeanPostProcessorpostProcessAfterInstantiation执行的地方了,接着点进源码品尝一番,坐标定位:AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {
		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			// 这里可以知道就算返回的是空的,依旧可以拿到bean
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

🍉 可以看到,此时Object current = processor.postProcessAfterInitialization(result, beanName)执行了实例化之后的后置处理器,同时有个点我们可以注意一下,这里对current进行了判空的操作,也就是说,我们在这里对bean对象进行自己的操作(比如自己进行赋值等),如果返回的是空,那么就返回原来的bean Demo中就在这里对bean重新进行了赋值操作

Bean出生了

🍉 至此,Bean已经完整的度过了他的生命周期了,历经了实例化,实例化的前后后置处理器,属性赋值,初始化的前后后置处理器,然后形成了一个Bean,看下我们的控制台打印

=====================spring容器【create by:Cocowwy】==================================
student执行实例化之前的方法【InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation】
student执行实例化之后的方法【InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation】
对name属性进行赋值
对sex属性进行赋值
对studentNo属性进行赋值
执行【BeanNameAware接口】part:1======【AbstractAutowireCapableBeanFactory:invokeAwareMethods】
执行Student类的BeanNameAware接口方法
执行【EnvironmentAware接口】part:2======【ApplicationContextAwareProcessor:invokeAwareInterfaces】
执行Student类的EnvironmentAware接口方法
student执行初始化之前的方法【BeanPostProcessor#postProcessBeforeInitialization】
student执行初始化之后的方法【BeanPostProcessor#postProcessAfterInitialization】
对name属性进行赋值
Student{name='BeanPostProcessor#postProcessAfterInitialization', studentNo='PC66715', sex='boy'}

🍉 配置文件中我们设置的BeanName为Cocowwy,但是为什么这里的name为BeanPostProcessor#postProcessAfterInitialization?

❓ 如果上面的文章有认真阅读的话,熟悉了Bean的生命周期的话,那么这种小问题就难不倒你了~

⚡️ 到此,SpringBean生命周期中的几个重要的后置处理器以及Aware接口的流程已经走完 🔚如果有疑问或者有不对的地方欢迎在下方留言!

⭐️如果需要源码的可以上本人的Github【Spring-Framework-Cocowwy】上拉喔~⭐️

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值