spring-boot源码分析之BeanFactory · 壹

共 5615字,需浏览 12分钟

 ·

2021-09-06 15:38


前言

今天原本是打算分析beanFactory的,但由于昨天我们有一部分内容还没有分享完,所以今天就先开个倒车,把昨天的内容先讲清楚了再说别的,因此今天的内容主要就是对昨天分享内容的的补充。

当然,昨天我们分享的内容beanDefinitionNames也算是BeanFactory的核心属性,所以也不能说完全没有关系:

而且从源码中我们可以看出来,beanDefinitionNamesbeanDefinitionMap这些属性的初始化大小,这也算是在学习beanFactory的相关知识吧。

BeanFactory

beanDefinitionNames内容补充

正式开始之前,我们先把昨天遗留的问题解决了。昨天,我们分享了一张beanDefinitionNames初始化的时序图,但是由于有一些内容没有梳理清楚,所以这里先做个补充。

调用过程各方法作用

SpringApplication这里就不做过多说明了,我们在前面最开始的时候就已经分析过这个类的run方法,当时也已经介绍过这个类的这些方法,他们的主要作用就是为了初始化容器,在SpringApplication的最后一个refresh方法中,最后会调用AbstractApplicationContext自身的refresh方法,这里的AbstractApplicationContextApplicationContext的抽象实现,它实现了ConfigurableApplicationContext接口(ConfigurableApplicationContext继承了ApplicationContext),我们的AnnotationConfigReactiveWebServerApplicationContext(默认容器)就是继承自它,不过并不是直接继承,它的父类继承了AbstractApplicationContext,关于容器这块的继承关系,我们改天抽个时间,专门分析下。

大部分继承了AbstractApplicationContext的容器都没有重写refresh方法,就算重写了这个方法,其内部也是调用了父类的refresh方法:

我们看下refresh的实现源码:

 public void refresh() throws BeansException, IllegalStateException {
  synchronized (this.startupShutdownMonitor) {
   // 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);

    // Invoke factory processors registered as beans in the context.
    invokeBeanFactoryPostProcessors(beanFactory);

    // Register bean processors that intercept bean creation.
    registerBeanPostProcessors(beanFactory);

    // 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();
   }
  }
 }

refresh方法内部,调用了很多其他方法,其中prepareRefresh的作用是为我们下面的刷新操作做准备,其内部主要是对配置的一些初始化操作:

obtainFreshBeanFactory方法的作用是刷新beanFactory,主要是对beanFactory进行一些初始化操作,如果beanFactory已经存在,会将已有的beanFactory销毁,然后重新创建,最后将beanFactory返回:

prepareBeanFactory方法的作用是对BeanFactory进行一些赋值和设置,为容器初始化操作做准备:

postProcessBeanFactory方法就是我们昨天提到的会进行包扫描的那个方法,但由于basePackagesannotatedClasses都是空,所以其中的scan方法并不会被执行。这个方法实际的作用是,后置处理BeanFactory

invokeBeanFactoryPostProcessors方法的作用是,实例化并调用所有注册的BeanFactory的后置处理器。我们昨天说的beanDefinitionNamesbeanDefinitionMap就是通过这个方法最终完成初始化的:

registerBeanPostProcessors方法和它名字一样,它的作用就是注册bean的后置处理器:

initMessageSource方法是进行消息源初始化的,主要是对web应用消息国际化提供支持的:

initApplicationEventMulticaster,这个方法是初始化spring boot应用时间广播的,如果不指定的话,默认情况下为我们指定的是SimpleApplicationEventMulticaster

onRefresh,这个方法是提供给子类初始化其他特殊bean对象的,默认实现为空,子类可根据需要重写:

registerListeners方法是用来注册事件监听器的:

finishBeanFactoryInitialization,完成beanFactory初始化,同时在方法内部会实例化剩余的单例类(不包括懒加载部分):

finishRefresh,完成刷新,主要进行一些清理、刷新、事件推送等操作:

总结

经过今天的补充之后,我相信各位小伙伴一定也对spring boot的启动和初始化过程有了更深刻的认识,因为我就是这样的感受。相比于昨天分享完内容的感受,今天我感觉整体来说要更好。一方面感觉spring boot启动和初始化的流程更清晰了,而且由于最近这几天一直在看spring boot的源码,看的多了感觉就没有那么难了,毕竟书读百遍其意自现,代码也是大同小异;另一方面在梳理分析的过程中,让我也能够清晰地看到下一步要分享的内容,明确后面的前进方向,这也算是意外的收获吧。

- END -


浏览 38
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报