天天看點

spring的上下文執行流程(refresh()底層原理及掃描流程)

作者:wuweixianzheng

以AnnotationConfigApplicationContext為例子:

1、this

a.在調用AnnotationConfigApplicationContext的構造方法之前,會調用父類GenericApplicationContext的無參構造方法,會構造一個BeanFactory,為DefaultListableBeanFactory。

b.new AnnotatedBeanDefinitionReader,(主要為了添加一些基礎的PostProcessor,同時通過reader進行BeanDefinition的注冊,同時對BeanFactory設定和添加PostProcessor(後置處理器))

c.new ClassPathBeanDefinitionScanner,主要作用可以用來掃描得到并注冊BeanDefinition(可參考 bean掃描流程圖 很詳細了,在下面)

2、register

使用第一步中的reader注冊AppConfig為BeanDefinition,類型為AnnotatedGenericBeanDefinition

3、refresh

a.prepareRefresh(),主要作用記錄啟動時間,并且可以允許子容器設定一些内容到Environment中,驗證Environment中是否包括了必須要有的屬性

b.obtainFreshBeanFactory(),進行BeanFactory的refresh,最終調用子類的方法産生一個BeanFactory

c.prepareBeanFactory(beanFactory),為beanFactory設定一些屬性,比如設定表達式解析器、後置處理器、ResolvableDependency、DependencyInterface等等

d.postProcessBeanFactory為了給子類提供擴充(子類可以繼續向beanFactory中添加東西)

e.invokeBeanFactoryPostProcessors(beanFactory),拿到context中所有的beanFactoryPostProcessors,執行BeanFactoryPostProcessor(這一步是spring中的一個重點),到此BeanDefinition就注冊到BeanFactory了

f.registerBeanPostProcessors,注冊一些程式員自己寫的bean處理器

g、initMessageSource():假如BeanFactory中有"messageSource"的BeanDefinition,那麼就會把這個Bean對象建立出來并指派給ApplicationContext的messageSource屬性,讓ApplicationContext擁有國際化的功能

h.initApplicationEventMulticaster():如果BeanFactory中有"applicationEventMulticaster"的BeanDefinition,那麼就會把這個Bean對象建立出來并指派給ApplicationContext的applicationEventMulticaster屬性,讓ApplicationContext擁有事件釋出的功能

i.onRefresh():提供給AbstractApplicationContext的子類進行擴充(springboot中用來啟動内置tomcat)

j. registerListeners():從BeanFactory中擷取ApplicationListener類型的beanName,然後添加到ApplicationContext中的事件廣播器applicationEventMulticaster中去,到這一步因為FactoryBean還沒有調用getObject()方法生成Bean對象,是以這裡要在根據類型找一下ApplicationListener,記錄一下對應的beanName.

k. finishBeanFactoryInitialization(beanFactory):完成BeanFactory的初始化,主要就是執行個體化非懶加載的單例Bean。

l. finishRefresh():BeanFactory的初始化完(設定ApplicationContext的lifecycleProcessor、調用lifecycleProcessor的onRefresh()方法,然後調用它的start()方法,這一步必須是是DefaultLifecycleProcessor才調用,這就是ApplicationContext的生命周期擴充機制、釋出ContextRefreshedEvent事件)

spring的上下文執行流程(refresh()底層原理及掃描流程)

上下文執行流程圖1

spring的上下文執行流程(refresh()底層原理及掃描流程)

上下文執行流程圖2

spring的上下文執行流程(refresh()底層原理及掃描流程)

bean掃描流程圖