深入理解 Spring Bean 生命周期(附源码分析)

前言:

Spring Bean 的生命周期是面试中 Spring 系列的一个高频问题,本篇我们将从源码方面来剖析 Spring Bean 的生命周期。

Spring 知识储备传送门:

深入理解 Spring IOC 底层实现机制(refresh 方法源码分析)

Spring 源码之 BeanDefinition 加载分析

Spring Bean 生命周期

我们知道 Spring 项目中,bean 都是交由 Spring IOC 容器来管理,由 IOC 容器帮我们帮我们管理 bean 对象的创建和销毁,在 Spring IOC 容器中,Spring Bean 的生命周期大致如下:

  • 实例化:Spring 容器启动时,通过反射实例化 Bean。
  • 属性赋值:实例化后,Spring 会对 Bean 的属性进行赋值。
  • 执行前置处理方法:BeanPostProcessors 的 postProcessBeforeInitialization 方法。
  • 执行初始化方法:执行一些 Bean 的初始化操作,对应 init-method。
  • 执行后置处理方法:BeanPostProcessors 的 postProcessAfterInitialization 方法。
  • 使用:Bean 初始化完毕,被应用程序使用。
  • 销毁:关闭 IOC 容器的时候,Spring 会处理配置了销毁方法的 Bean。

Spring Bean 生命周期主脉络图

简单的画了一个 Spring Bean 生命周期的脉络图,帮助理解源码的同时加深我们对 Spring Bean 生命周期的理解。

在这里插入图片描述

Spring Bean 生命周期源码分析

我们知道非懒加载的 Bean 都是通过 AbstractApplicationContext#finishBeanFactoryInitialization 方法来创建的,下面我们以该方法为入口来分析一下 Spring Bean 的生命周期。

AbstractApplicationContext#finishBeanFactoryInitialization 方法源码分析

finishBeanFactoryInitialization 方法对 BeanFactory 做了一些设置,并继续调用了 DefaultListableBeanFactory#preInstantiateSingletons 方法进行非懒加载的 Bean 的实例化。

//beanFactory 创建完成 初始化单例bean
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   
   
    //给 beanFactory 设置 ConversionService
    if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
   
   
        beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
    }
    //给 beanFactory 设置 值解析器
    if (!beanFactory.hasEmbeddedValueResolver()) {
   
   
        beanFactory.addEmbeddedValueResolver((strVal) -> {
   
   
            return this.getEnvironment().resolvePlaceholders(strVal);
        });
    }
    //获取所有的 LoadTimeWeaverAware 织入  Aspect AOP  相关
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    String[] var3 = weaverAwareNames;
    int var4 = weaverAwareNames.length;

    for(int var5 = 0; var5 < var4; ++var5) {
   
   
        String weaverAwareName = var3[var5];
        //初始化 LoadTimeWeaverAware  bean
        this.getBean(weaverAwareName);
    }
    //设置临时类加载器为 null
    beanFactory.setTempClassLoader((ClassLoader)null);
    //冻结BeanDefinition
    beanFactory.freezeConfiguration();
    //预实例化单例非懒加载 lazy-init 的 bean 调用了 DefaultListableBeanFactory#preInstantiateSingletons 方法
    beanFactory.preInstantiateSingletons();
}

DefaultListableBeanFactory#preInstantiateSingletons 方法源码分析

DefaultListableBeanFactory#preInstantiateSingletons 方法设置了 BeanFactory 的一些属性,调用了 DefaultListableBeanFactory#preInstantiateSingletons 方法

//beanFactory 创建完成 初始化单例bean
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   
   
    //给 beanFactory 设置 ConversionService
    if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
   
   
        beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
    }
    //给 beanFactory 设置 值解析器
    if (!beanFactory.hasEmbeddedValueResolver()) {
   
   
        beanFactory.addEmbeddedValueResolver((strVal) -> {
   
   
            return this.getEnvironment().resolvePlaceholders(strVal);
        });
    }
    //获取所有的 LoadTimeWeaverAware 织入  Aspect AOP  相关
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    String[] var3 = weaverAwareNames;
    int var4 = weaverAwareNames.length;

    for(int var5 = 0; var5 < var4; ++var5) {
   
   
        String weaverAwareName = var3[var5];
        //初始化 LoadTimeWeaverAware  bean
        this.getBean(weaverAwareName);
    }
    //设置临时类加载器为 null
    beanFactory.setTempClassLoader((ClassLoader)null);
    //冻结BeanDefinition
    beanFactory.freezeConfiguration();
    //预实例化单例非懒加载 lazy-init 的 bean
    beanFactory.preInstantiateSingletons();
}

DefaultListableBeanFactory#preInstantiateSingletons方法源码分析

DefaultListableBeanFactory#preInstantiateSingletons 循环遍历了 BeanDefinitions,核心是调用了 AbstractBeanFactory#getBean 方法。

//对懒加载的 bean 进行预实例化
public void preInstantiateSingletons() throws BeansException {
   
   
	if (this.logger.isTraceEnabled()) {
   
   
		this.logger.trace("Pre-instantiating singletons in " + this);
	}
	//获取所有需要实例化的 beanDefinitionNames
	List<String> beanNames = new ArrayList(this.beanDefinitionNames);
	//迭代器遍历
	Iterator var2 = beanNames.iterator();

	while(true) {
   
   
		String beanName;
		Object bean;
		do {
   
   
			//非工厂bean 逻辑
			while(true) {
   
   
				//定义 RootBeanDefinition
				RootBeanDefinition bd;
				do {
   
   
					//beanDefinition 懒加载 
					do {
   
   
						//非 单例bean 
						do {
   
   
							//抽象bean(懒加载 非单例 抽象)
							if (!var2.hasNext()) {
   
   
								//获取迭代器
								var2 = beanNames.iterator();

								while(var2.hasNext()) {
   
   
									//获取beanName
									beanName = (String)var2.next();
									// 获取beanName对应的bean实例
									Object singletonInstance = this.getSingleton(beanName);
									//singletonInstance 是否实现了 SmartInitializingSingleton 接口
									if (singletonInstance instanceof SmartInitializingSingleton) {
   
   
										//获取  StartupStep
										StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);
										//类型转换
										SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
										//触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法
										if (System.getSecurityManager() != null) {
   
   
											AccessController.doPrivileged(() -> {
   
   
												smartSingleton.afterSingletonsInstantiated();
												return null;
											}, this.getAccessControlContext())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值