文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

SpringBoot源码之Bean的生命周期是什么

2023-07-06 02:53

关注

本文小编为大家详细介绍“SpringBoot源码之Bean的生命周期是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“SpringBoot源码之Bean的生命周期是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

入口方法为SpringApplication#run()

SpringApplication#run()

public ConfigurableApplicationContext run(String... args) {long startTime = System.nanoTime();DefaultBootstrapContext bootstrapContext = createBootstrapContext();ConfigurableApplicationContext context = null;configureHeadlessProperty();SpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting(bootstrapContext, this.mainApplicationClass);try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);Banner printedBanner = printBanner(environment);context = createApplicationContext();context.setApplicationStartup(this.applicationStartup);prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);refreshContext(context);afterRefresh(context, applicationArguments);Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);}listeners.started(context, timeTakenToStartup);callRunners(context, applicationArguments);}catch (Throwable ex) {if (ex instanceof AbandonedRunException) {throw ex;}handleRunFailure(context, ex, listeners);throw new IllegalStateException(ex);}try {if (context.isRunning()) {Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);listeners.ready(context, timeTakenToReady);}}catch (Throwable ex) {if (ex instanceof AbandonedRunException) {throw ex;}handleRunFailure(context, ex, null);throw new IllegalStateException(ex);}return context;}

SpringApplication#run()=> SpringApplication#refreshContext(context)=> SpringApplication#refresh(context)=>ConfigurableApplicationContext#refresh()=>AbstractApplicationContext#refresh()

@Overridepublic 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();// Instantiate all remaining (non-lazy-init) singletons.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();}}}

SpringApplication#run()=> SpringApplication#refreshContext(context)=> SpringApplication#refresh(context)=>ConfigurableApplicationContext#refresh()=>AbstractApplicationContext#refresh()=>AbstractApplicationContext#finishBeanFactoryInitialization()=>ConfigurableListableBeanFactory#preInstantiateSingletons()=>DefaultListableBeanFactory#preInstantiateSingletons()

@Overridepublic void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) {Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);if (bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isEagerInit()) {getBean(beanName);}}else {// 此处就是初始化bean的方法getBean(beanName);}}}// Trigger post-initialization callback for all applicable beans...for (String beanName : beanNames) {// 此处就是解决循环依赖的代码Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton smartSingleton) {StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);smartSingleton.afterSingletonsInstantiated();smartInitialize.end();}}}

解决循环依赖的代码如下:

protected Object getSingleton(String beanName, boolean allowEarlyReference) {// 尝试从缓存中获取成品的目标对象,如果存在,则直接返回  Object singletonObject = this.singletonObjects.get(beanName);  // 如果缓存中不存在目标对象,则判断当前对象是否已经处于创建过程中,在前面的讲解中,第一次尝试获取A对象  // 的实例之后,就会将A对象标记为正在创建中,因而最后再尝试获取A对象的时候,这里的if判断就会为true  if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {    synchronized (this.singletonObjects) {      singletonObject = this.earlySingletonObjects.get(beanName);      if (singletonObject == null && allowEarlyReference) {        // 这里的singletonFactories是一个Map,其key是bean的名称,而值是一个ObjectFactory类型的        // 对象,这里对于A和B而言,调用图其getObject()方法返回的就是A和B对象的实例,无论是否是半成品        ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);        if (singletonFactory != null) {          // 获取目标对象的实例          singletonObject = singletonFactory.getObject();          this.earlySingletonObjects.put(beanName, singletonObject);          this.singletonFactories.remove(beanName);        }      }    }  }  return singletonObject;}

解决原理如下:

SpringApplication#run()=> SpringApplication#refreshContext(context)=> SpringApplication#refresh(context)=>ConfigurableApplicationContext#refresh()=>AbstractApplicationContext#refresh()=>AbstractApplicationContext#finishBeanFactoryInitialization()=>ConfigurableListableBeanFactory#preInstantiateSingletons()=>DefaultListableBeanFactory#preInstantiateSingletons()=>AbstractBeanFactory#getBean() => AbstractBeanFactory#doGetBean()=>AbstractBeanFactory#createBean()=>AbstractAutowireCapableBeanFactory#createBean()=>AbstractAutowireCapableBeanFactory#doCreateBean()

bean的生命周期:

调用InstantiationAwareBeanPostProcessor# postProcessBeforeInstantiation
跟进doCreateBean()

@Override  protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)        throws BeanCreationException {       if (logger.isTraceEnabled()) {        logger.trace("Creating instance of bean '" + beanName + "'");     }     RootBeanDefinition mbdToUse = mbd;       // Make sure bean class is actually resolved at this point, and     // clone the bean definition in case of a dynamically resolved Class   // which cannot be stored in the shared merged bean definition.   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);     if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {        mbdToUse = new RootBeanDefinition(mbd);        mbdToUse.setBeanClass(resolvedClass);     }       // Prepare method overrides.     try {        mbdToUse.prepareMethodOverrides();     }     catch (BeanDefinitionValidationException ex) {        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),              beanName, "Validation of method overrides failed", ex);     }       try {        // 1.调用InstantiationAwareBeanPostProcessor# postProcessBeforeInstantiation      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);        if (bean != null) {           return bean;        }     }     catch (Throwable ex) {        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,              "BeanPostProcessor before instantiation of bean failed", ex);     }       try {    // 跟进doCreateBean()      Object beanInstance = doCreateBean(beanName, mbdToUse, args);        if (logger.isTraceEnabled()) {           logger.trace("Finished creating instance of bean '" + beanName + "'");        }        return beanInstance;     }     catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {        // A previously detected exception with proper bean creation context already,        // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.      throw ex;     }     catch (Throwable ex) {        throw new BeanCreationException(              mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);     }  }

创建bean实例

跟进populateBean()
跟进initializeBean()

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)        throws BeanCreationException {       // Instantiate the bean.     BeanWrapper instanceWrapper = null;     if (mbd.isSingleton()) {        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);     }     if (instanceWrapper == null) {   // 2.创建bean实例       instanceWrapper = createBeanInstance(beanName, mbd, args);     }     Object bean = instanceWrapper.getWrappedInstance();     Class<?> beanType = instanceWrapper.getWrappedClass();     if (beanType != NullBean.class) {        mbd.resolvedTargetType = beanType;     }       // Allow post-processors to modify the merged bean definition.     synchronized (mbd.postProcessingLock) {        if (!mbd.postProcessed) {           try {            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);           }           catch (Throwable ex) {              throw new BeanCreationException(mbd.getResourceDescription(), beanName,                    "Post-processing of merged bean definition failed", ex);           }           mbd.markAsPostProcessed();        }     }       // Eagerly cache singletons to be able to resolve circular references     // even when triggered by lifecycle interfaces like BeanFactoryAware.   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&           isSingletonCurrentlyInCreation(beanName));     if (earlySingletonExposure) {        if (logger.isTraceEnabled()) {           logger.trace("Eagerly caching bean '" + beanName +                 "' to allow for resolving potential circular references");        }        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));     }       // Initialize the bean instance.     Object exposedObject = bean;     try {  // 跟进populateBean()      populateBean(beanName, mbd, instanceWrapper);       // 跟进initializeBean()       exposedObject = initializeBean(beanName, exposedObject, mbd);     }     catch (Throwable ex) {        if (ex instanceof BeanCreationException bce && beanName.equals(bce.getBeanName())) {           throw bce;        }        else {           throw new BeanCreationException(mbd.getResourceDescription(), beanName, ex.getMessage(), ex);        }     }       if (earlySingletonExposure) {        Object earlySingletonReference = getSingleton(beanName, false);        if (earlySingletonReference != null) {           if (exposedObject == bean) {              exposedObject = earlySingletonReference;           }           else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {              String[] dependentBeans = getDependentBeans(beanName);              Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);              for (String dependentBean : dependentBeans) {                 if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {                    actualDependentBeans.add(dependentBean);                 }              }              if (!actualDependentBeans.isEmpty()) {                 throw new BeanCurrentlyInCreationException(beanName,                       "Bean with name '" + beanName + "' has been injected into other beans [" +                       StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +                       "] in its raw version as part of a circular reference, but has eventually been " +                       "wrapped. This means that said other beans do not use the final version of the " +                       "bean. This is often the result of over-eager type matching - consider using " +                       "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");              }           }        }     }       // Register bean as disposable.     try {        registerDisposableBeanIfNecessary(beanName, bean, mbd);     }     catch (BeanDefinitionValidationException ex) {        throw new BeanCreationException(              mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);     }       return exposedObject;  }

调用InstantiationAwareBeanPostProcessor# postProcessAfterInstantiation

注入bean属性

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {     if (bw == null) {        if (mbd.hasPropertyValues()) {           throw new BeanCreationException(                 mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");        }        else {           // Skip property population phase for null instance.           return;        }     }       if (bw.getWrappedClass().isRecord()) {        if (mbd.hasPropertyValues()) {           throw new BeanCreationException(                 mbd.getResourceDescription(), beanName, "Cannot apply property values to a record");        }        else {           // Skip property population phase for records since they are immutable.           return;        }     }          // 3.调用InstantiationAwareBeanPostProcessor# postProcessAfterInstantiation      for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {           if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {              return;           }        }     }       PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);       int resolvedAutowireMode = mbd.getResolvedAutowireMode();     if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);        // Add property values based on autowire by name if applicable.        if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {           autowireByName(beanName, mbd, bw, newPvs);        }        // Add property values based on autowire by type if applicable.        if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {           autowireByType(beanName, mbd, bw, newPvs);        }        pvs = newPvs;     }     if (hasInstantiationAwareBeanPostProcessors()) {        if (pvs == null) {          pvs = mbd.getPropertyValues();        }        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {           PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);           if (pvsToUse == null) {              return;           }           pvs = pvsToUse;        }     }       boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);     if (needsDepCheck) {        PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);        checkDependencies(beanName, mbd, filteredPds, pvs);     }       if (pvs != null) {  // 4.注入属性        applyPropertyValues(beanName, mbd, bw, pvs);     }  }

设置Aware接口的属性

调用BeanPostProcessor的初始化前置方法

先((InitializingBean) bean).afterPropertiesSet(),后调用init-method方法,进行初始化操作

调用BeanPostProcessor的初始化后置方法

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {    // 5.设置Aware接口的属性   invokeAwareMethods(beanName, bean);       Object wrappedBean = bean;     if (mbd == null || !mbd.isSynthetic()) {  // 5.调用BeanPostProcessor的初始化前置方法        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);     }       try {  // 6.调用init-method方法,进行初始化操作        invokeInitMethods(beanName, wrappedBean, mbd);     }     catch (Throwable ex) {        throw new BeanCreationException(              (mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex);     }     if (mbd == null || !mbd.isSynthetic()) {       // 7. 调用BeanPostProcessor的初始化后置方法      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);     }       return wrappedBean;  }

读到这里,这篇“SpringBoot源码之Bean的生命周期是什么”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯