更新時(shí)間:2022年01月11日11時(shí)46分 來(lái)源:傳智教育 瀏覽次數(shù):
refresh 是 AbstractApplicationContext 中的一個(gè)方法,負(fù)責(zé)初始化 ApplicationContext 容器,容器必須調(diào)用 refresh 才能正常工作。它的內(nèi)部主要會(huì)調(diào)用 12 個(gè)方法,我們把它們稱(chēng)為 refresh 的 12 個(gè)步驟:
1. prepareRefresh
2. obtainFreshBeanFactory
3. prepareBeanFactory
4. postProcessBeanFactory
5. invokeBeanFactoryPostProcessors
6. registerBeanPostProcessors
7. initMessageSource
8. initApplicationEventMulticaster
9. onRefresh
10. registerListeners
11. finishBeanFactoryInitialization
12. finishRefresh
1 為準(zhǔn)備環(huán)境
2 3 4 5 6 為準(zhǔn)備 BeanFactory
7 8 9 10 12 為準(zhǔn)備 ApplicationContext
11 為初始化 BeanFactory 中非延遲單例 bean
* 這一步創(chuàng)建和準(zhǔn)備了 Environment 對(duì)象,它作為 ApplicationContext 的一個(gè)成員變量
* Environment 對(duì)象的作用之一是為后續(xù) @Value,值注入時(shí)提供鍵值
* Environment 分成三個(gè)主要部分
* systemProperties - 保存 java 環(huán)境鍵值
* systemEnvironment - 保存系統(tǒng)環(huán)境鍵值
* 自定義 PropertySource - 保存自定義鍵值,例如來(lái)自于 *.properties 文件的鍵值
* 這一步獲取(或創(chuàng)建) BeanFactory,它也是作為 ApplicationContext 的一個(gè)成員變量
* BeanFactory 的作用是負(fù)責(zé) bean 的創(chuàng)建、依賴(lài)注入和初始化,bean 的各項(xiàng)特征由 BeanDefinition 定義
* BeanDefinition 作為 bean 的設(shè)計(jì)藍(lán)圖,規(guī)定了 bean 的特征,如單例多例、依賴(lài)關(guān)系、初始銷(xiāo)毀方法等
* BeanDefinition 的來(lái)源有多種多樣,可以是通過(guò) xml 獲得、配置類(lèi)獲得、組件掃描獲得,也可以是編程添加
* 所有的 BeanDefinition 會(huì)存入 BeanFactory 中的 beanDefinitionMap 集合
* 這一步會(huì)進(jìn)一步完善 BeanFactory,為它的各項(xiàng)成員變量賦值
* beanExpressionResolver 用來(lái)解析 SpEL,常見(jiàn)實(shí)現(xiàn)為 StandardBeanExpressionResolver
* propertyEditorRegistrars 會(huì)注冊(cè)類(lèi)型轉(zhuǎn)換器
* 它在這里使用了 ResourceEditorRegistrar 實(shí)現(xiàn)類(lèi)
* 并應(yīng)用 ApplicationContext 提供的 Environment 完成 ${ } 解析
* registerResolvableDependency 來(lái)注冊(cè) beanFactory 以及 ApplicationContext,讓它們也能用于依賴(lài)注入
* beanPostProcessors 是 bean 后處理器集合,會(huì)工作在 bean 的生命周期各個(gè)階段,此處會(huì)添加兩個(gè):
* ApplicationContextAwareProcessor 用來(lái)解析 Aware 接口
* ApplicationListenerDetector 用來(lái)識(shí)別容器中 ApplicationListener 類(lèi)型的 bean
* 這一步是空實(shí)現(xiàn),留給子類(lèi)擴(kuò)展。
* 一般 Web 環(huán)境的 ApplicationContext 都要利用它注冊(cè)新的 Scope,完善 Web 下的 BeanFactory
* 這里體現(xiàn)的是模板方法設(shè)計(jì)模式
* 這一步會(huì)調(diào)用 beanFactory 后處理器
* beanFactory 后處理器,充當(dāng) beanFactory 的擴(kuò)展點(diǎn),可以用來(lái)補(bǔ)充或修改 BeanDefinition
* 常見(jiàn)的 beanFactory 后處理器有
* ConfigurationClassPostProcessor – 解析 @Configuration、@Bean、@Import、@PropertySource 等
* PropertySourcesPlaceHolderConfigurer – 替換 BeanDefinition 中的 ${ }
* MapperScannerConfigurer – 補(bǔ)充 Mapper 接口對(duì)應(yīng)的 BeanDefinition
* 這一步是繼續(xù)從 beanFactory 中找出 bean 后處理器,添加至 beanPostProcessors 集合中
* bean 后處理器,充當(dāng) bean 的擴(kuò)展點(diǎn),可以工作在 bean 的實(shí)例化、依賴(lài)注入、初始化階段,常見(jiàn)的有:
* AutowiredAnnotationBeanPostProcessor 功能有:解析 @Autowired,@Value 注解
* CommonAnnotationBeanPostProcessor 功能有:解析 @Resource,@PostConstruct,@PreDestroy
* AnnotationAwareAspectJAutoProxyCreator 功能有:為符合切點(diǎn)的目標(biāo) bean 自動(dòng)創(chuàng)建代理
* 這一步是為 ApplicationContext 添加 messageSource 成員,實(shí)現(xiàn)國(guó)際化功能
* 去 beanFactory 內(nèi)找名為 messageSource 的 bean,如果沒(méi)有,則提供空的 MessageSource 實(shí)現(xiàn)
* 這一步為 ApplicationContext 添加事件廣播器成員,即 applicationContextEventMulticaster
* 它的作用是發(fā)布事件給監(jiān)聽(tīng)器
* 去 beanFactory 找名為 applicationEventMulticaster 的 bean 作為事件廣播器,若沒(méi)有,會(huì)創(chuàng)建默認(rèn)的事件廣播器
* 之后就可以調(diào)用 ApplicationContext.publishEvent(事件對(duì)象) 來(lái)發(fā)布事件
* 這一步是空實(shí)現(xiàn),留給子類(lèi)擴(kuò)展
* SpringBoot 中的子類(lèi)在這里準(zhǔn)備了 WebServer,即內(nèi)嵌 web 容器
* 體現(xiàn)的是模板方法設(shè)計(jì)模式
* 這一步會(huì)從多種途徑找到事件監(jiān)聽(tīng)器,并添加至 applicationEventMulticaster
* 事件監(jiān)聽(tīng)器顧名思義,用來(lái)接收事件廣播器發(fā)布的事件,有如下來(lái)源
* 事先編程添加的
* 來(lái)自容器中的 bean
* 來(lái)自于 @EventListener 的解析
* 要實(shí)現(xiàn)事件監(jiān)聽(tīng)器,只需要實(shí)現(xiàn) ApplicationListener 接口,重寫(xiě)其中 onApplicationEvent(E e) 方法即可
* 這一步會(huì)將 beanFactory 的成員補(bǔ)充完畢,并初始化所有非延遲單例 bean
* conversionService 也是一套轉(zhuǎn)換機(jī)制,作為對(duì) PropertyEditor 的補(bǔ)充
* embeddedValueResolvers 即內(nèi)嵌值解析器,用來(lái)解析 @Value 中的 ${ },借用的是 Environment 的功能
* singletonObjects 即單例池,緩存所有單例對(duì)象
* 對(duì)象的創(chuàng)建都分三個(gè)階段,每一階段都有不同的 bean 后處理器參與進(jìn)來(lái),擴(kuò)展功能
* 這一步會(huì)為 ApplicationContext 添加 lifecycleProcessor 成員,用來(lái)控制容器內(nèi)需要生命周期管理的 bean
* 如果容器中有名稱(chēng)為 lifecycleProcessor 的 bean 就用它,否則創(chuàng)建默認(rèn)的生命周期管理器
* 準(zhǔn)備好生命周期管理器,就可以實(shí)現(xiàn)
* 調(diào)用 context 的 start,即可觸發(fā)所有實(shí)現(xiàn) LifeCycle 接口 bean 的 start
* 調(diào)用 context 的 stop,即可觸發(fā)所有實(shí)現(xiàn) LifeCycle 接口 bean 的 stop
* 發(fā)布 ContextRefreshed 事件,整個(gè) refresh 執(zhí)行完成
猜你喜歡:SpringBoot 2.X有什么新特性?與1.X有什么區(qū)別?
鴻蒙相較于安卓系統(tǒng)有哪些優(yōu)點(diǎn)?
2021-12-29鴻蒙系統(tǒng)和安卓有哪些區(qū)別?鴻蒙會(huì)取代安卓嗎?
2021-12-29DevEco Studio項(xiàng)目結(jié)構(gòu)介紹【Java開(kāi)發(fā)手機(jī)應(yīng)用】
2021-12-22鴻蒙OS系統(tǒng)開(kāi)發(fā)初體驗(yàn):預(yù)安裝DevEco Studio工具
2021-12-22Log4j有什么作用?它主要由哪三部分組成?【Log4j面試問(wèn)題】
2021-12-16三目運(yùn)算符什么意思?三目運(yùn)算符怎么用?
2021-12-14北京校區(qū)