SpringBoot面试篇(3)

Bean的生命周期

一,bean生命周期概述

Spring Boot 中的 Bean 生命周期通常遵循以下过程:

  1. 实例化:容器根据配置或注解等信息创建 Bean 的实例。
  2. 属性设置:容器将依赖注入到 Bean 的属性中。
  3. 初始化方法调用:如果 Bean 实现了 InitializingBean 接口,或者在配置中使用 @PostConstruct 注解标记了初始化方法,容器会在依赖注入完成后调用这些初始化方法。
  4. 使用:Bean 可以被其他 Bean 或组件使用。
  5. 销毁方法调用:如果 Bean 实现了 DisposableBean 接口,或者在配置中使用 @PreDestroy 注解标记了销毁方法,容器在 Bean 被销毁之前会调用这些方法。

二,Bean生命周期源码

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 设置转换服务(ConversionService),如果容器中包含并且类型匹配,则进行设置
    if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
        beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
    }

    // 如果容器中没有嵌入式值解析器,则添加一个,用于解析属性占位符
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver((strVal) -> {
            return this.getEnvironment().resolvePlaceholders(strVal);
        });
    }

    // 获取所有实现了 LoadTimeWeaverAware 接口的 Bean 的名称,然后依次获取这些 Bean 实例
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        this.getBean(weaverAwareName);
    }

    // 设置临时类加载器为空,并冻结配置,确保不再允许对 Bean 工厂的配置进行修改
    beanFactory.setTempClassLoader((ClassLoader)null);
    beanFactory.freezeConfiguration();

    // 预实例化所有单例 Bean,确保所有单例 Bean 都提前实例化
    beanFactory.preInstantiateSingletons();
}

接下来进入beanFactory.preInstantiateSingletons()这个方法中:

protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
    // 转换bean名称
    String beanName = this.transformedBeanName(name);
    
    // 检查单例实例是否存在
    Object sharedInstance = this.getSingleton(beanName);
    Object beanInstance;
    
    if (sharedInstance != null && args == null) {
        // 如果单例实例存在,则返回它
        if (this.logger.isTraceEnabled()) {
            if (this.isSingletonCurrentlyInCreation(beanName)) {
                this.logger.trace("正在返回尚未完全初始化的循环引用的单例bean'" + beanName + "'的急切缓存实例");
            } else {
                this.logger.trace("正在返回缓存的单例bean实例'" + beanName + "'");
            }
        }
        
        // 获取bean实例对象
        beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
    } else {
        // 处理创建新的bean实例
        
        // 检查原型作用域的bean是否正在创建中
        if (this.isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
        
        // 检查是否有父级Bean工厂以及bean定义是否存在
        BeanFactory parentBeanFactory = this.getParentBeanFactory();
        if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
            String nameToLookup = this.originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                AbstractBeanFactory abf = (AbstractBeanFactory) parentBeanFactory;
                return abf.doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
            }
            
            // 从父级Bean工厂获取bean
            // 为简洁起见,省略了代码
        }
        
        // 如果不仅执行类型检查,则将bean标记为已创建
        if (!typeCheckOnly) {
            this.markBeanAsCreated(beanName);
        }
        
        // 开始bean创建过程
        StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);
        
        try {
            // 检查是否指定了所需的类型
            if (requiredType != null) {
                Objects.requireNonNull(requiredType);
                beanCreation.tag("beanType", requiredType::toString);
            }
            
            // 获取合并的bean定义
            RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
            this.checkMergedBeanDefinition(mbd, beanName, args);
            
            // 处理依赖关系
            // 为简洁起见,省略了代码
            
            // 根据作用域创建bean实例
            // 为简洁起见,省略了代码
        } catch (BeansException var32) {
            // 处理bean创建过程中的异常
            beanCreation.tag("exception", var32.getClass().toString());
            beanCreation.tag("message", String.valueOf(var32.getMessage()));
            this.cleanupAfterBeanCreationFailure(beanName);
            throw var32;
        } finally {
            // 结束bean创建过程
            beanCreation.end();
        }
    }
    
    return this.adaptBeanInstance(name, beanInstance, requiredType);
}

doGetBean()方法字面意思就是创建实例,

三,情景再现

HR:说一下Bean的生命周期?

你:Bean的生命周期总的来说有四个阶段,分别是创建对象,初始化对象,使用以及销毁,且大部分工作是交还给Bean工厂的docreateBean()方法完成的:

  首先,在创建对象的过程中,先调用构造方法实例化对象,然后注入依赖,

  其次,在对象创建完毕之后会做一些初始化的操作:

             1.执行Aware感知接口的回调方法,

             2.执行Bean后置处理器的postProcessBeforeInitializer方法

             3.执行Initializerbean接口的回调

             4.执行Bean后置处理器,

  上述步骤之后,Bean的初始化就完成了,接下来就是程序从容器中获取Bean并使用,

  最后,在销毁容器之前,会先销毁对象。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值