從源碼分析Spring的生命週期

前言

  • 文章首發於微信公衆號老司機帶你從源碼擼spring的生命週期
  • Spring 中 Bean 的生命週期從容器的啓動到中止,涉及到的源碼主要是在 org.springframework.context.support.AbstractApplicationContext.refresh方法中,下面也是圍繞其中的邏輯進行講解。

開擼

【1】 prepareRefresh()java

內部其實很簡單,就是設置一些標誌,好比開始時間,激活的狀態等。spring

【2】prepareBeanFactory(beanFactory)緩存

作一些簡單的準備工做,此處再也不贅述!!!微信

【3】postProcessBeanFactory(beanFactory)session

主要的做用就是添加了一個後置處理器ServletContextAwareProcessorapp

【4】invokeBeanFactoryPostProcessors(beanFactory)post

調用容器中的全部的BeanFactoryPostProcessor中的postProcessBeanFactory方法,按照優先級調用,主要實現邏輯在 invokeBeanFactoryPostProcessors()ui

  1. 執行全部 BeanDefinitionRegistryPostProcessor(對 BeanFactoryPostProcessor 的擴展,運行在普通的實現類以前註冊 bean)的方法,一樣是內部按照優先級進行排序調用
  2. 對剩餘的進行按照優先級排序調用,一樣是內部進行排序執行

【5】registerBeanPostProcessors(beanFactory)this

註冊全部的BeanPostProcessor(後置處理器),按照優先級註冊,分別是 PriorityOrdered,Ordered,普通的,內部的。主要的實現邏輯在 PostProcessorRegistrationDelegate.registerBeanPostProcessors()spa

【6】initMessageSource() 註冊 MessageSource,提供消息國際化等功能

【7】initApplicationEventMulticaster();

註冊事件廣播器 ApplicationEventMulticaster,用於 spring 事件的廣播和事件監聽器的處理

【8】registerListeners()

註冊事件監聽器 ApplicationListener,而且廣播一些早期的事件,主要的邏輯在 org.springframework.context.support.AbstractApplicationContext.registerListeners

【9】finishBeanFactoryInitialization(beanFactory)

實例化全部非懶加載的 Bean,spring 生命週期中的主要方法,主要邏輯在 org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons,深刻進去其實就是 getBean()方法建立,詳情向下看。

【10】finishRefresh()

主要的功能是發佈事件 ContextRefreshedEvent

【11】destroyBeans()

容器啓動出現異常時銷燬 Bean

以上就是 Spring 容器啓動的過程,主要的邏輯都在 org.springframework.context.support.AbstractApplicationContext#refresh 中,其餘的都很容易理解,如今咱們着重分析一下單例 Bean 的建立過程,入口是第 9 步。

實例化單例 Bean

【1】debug 進入,實際主要的邏輯都在 org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons 方法中,邏輯以下:

//獲取全部注入到ioc容器中的bean定義信息
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
  //循環建立
  for (String beanName : beanNames) {
   RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            //非抽象,單例,非懶加載的bean初始化
   if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                //若是是FactoryBean
    if (isFactoryBean(beanName)) {
                    //getBean
     Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    //非FactoryBean,getBean
    else {
     getBean(beanName);
    }
   }
  }
複製代碼

以上源碼總結得知,最終實例化 Bean 的方法確定在 getBean 中的,debug 進入,得知 doGetBean 是大 boss,spring 源碼有趣的是最終的實現都是在 doxxxx()。

【2】AbstractBeanFactory#doGetBean,因爲篇幅過短,就不貼源碼了,只貼關鍵代碼

實例化的主要流程所有都在這裏,下面一一解析便可。

(1) Object sharedInstance = getSingleton(beanName)

從早期的緩存中獲取,若是存在返回 Bean,實例化

(2)BeanFactory parentBeanFactory = getParentBeanFactory()

從父工廠的中獲取 Bean

(3)if (mbd.isSingleton())

分單例和多例進行分開建立 Bean,這裏只分析單例 Bean 的建立

(4)sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); }

createBean 方法建立 Bean,進入 createBean()

​ a. Object bean = resolveBeforeInstantiation(beanName, mbdToUse):執行全部的 InstantiationAwareBeanPostProcessor 中的postProcessBeforeInstantiation,在實例化以前調用,返回 null 繼續下一步,返回一個 bean,那麼 bean 實例化完成,將調用其中的postProcessAfterInstantiation方法

​ b. Object beanInstance = doCreateBean(beanName, mbdToUse, args):建立 Bean 的完成過程

​ c. 進入doCreateBean,instanceWrapper = createBeanInstance(beanName, mbd, args):建立 Bean 的實例

​ d. populateBean(beanName, mbd, instanceWrapper):屬性裝配,執行 InstantiationAwareBeanPostProcessor 的postProcessAfterInstantiation,再執行postProcessProperties方法。

​ e. exposedObject = initializeBean(beanName, exposedObject, mbd):初始化 Bean,debug 進入

​ f. invokeAwareMethods(beanName, bean):調用BeanNameAwareBeanClassLoaderAwareBeanFactoryAware中的對應方法

​ g. wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName):調用 BeanPostProcessord 中的postProcessBeforeInitialization方法

​ h. invokeInitMethods(beanName, wrappedBean, mbd):執行InitializingBean中的afterPropertiesSet

​ i. wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName):調用BeanPostProcessor中的postProcessAfterInitialization方法

總結

以上是 spring 容器從啓動到銷燬的所有過程,根據源碼陳某畫了一張生命週期的圖,僅供參考,請勿轉載!!!

相關文章
相關標籤/搜索