容器啟動(dòng)過程
- 第一步先調(diào)用this()浓恳;構(gòu)造方法缺狠,這時(shí)父類構(gòu)造器會(huì)初始化容器的 beanFactory 屬性宇攻,屬性為DefaultListableBeanFactory尖淘,帶有存儲(chǔ)BeanDefinition 和單例 bean 的功能
- 新建一個(gè)注解Bean定義讀取器 new AnnotatedBeanDefinitionReader(this); 這個(gè)讀取器主要是初始化環(huán)境變量,以及注冊(cè) 一些創(chuàng)世紀(jì)的 BeanDefinition 【例如:ConfigurationClassPostProcessor著觉、AutowiredAnnotationBeanPostProcessor德澈、CommonAnnotationBeanPostProcessor、EventListenerMethodProcessor固惯、DefaultEventListenerFactory】
- 新建一個(gè)類路徑掃描器ClassPathBeanDefinitionScanner
- 容器調(diào)用register(componentClasses);把啟動(dòng)類注冊(cè)成BeanDefinition放入到容器中
- 啟動(dòng)Spring,調(diào)用 refresh() 方法去刷新容器
- prepareRefresh() 準(zhǔn)備刷新方法缴守,沒有做什么重要的事情葬毫,主要是設(shè)置了下容器的啟動(dòng)狀態(tài)
- 調(diào)用obtainFreshBeanFactory();獲取到容器的工廠,DefaultListableBeanFactory
- 調(diào)用prepareBeanFactory(beanFactory)
- 設(shè)置容器的類加載器
- 設(shè)置Spring容器中需要忽略的set方法
- ResourceEditorRegistrar注冊(cè)資源編輯器屡穗,當(dāng)Bean初始化的時(shí)候贴捡,構(gòu)造器上需要注入Spring資源相關(guān)的Bean時(shí),由該類注入
- 注冊(cè)三個(gè)BeanPostProcessor到容器中【ApplicationContextAwareProcessor (會(huì)在Bean初始化前村砂,調(diào)用烂斋,例如ApplicationContextAware接口,會(huì)注入ApplicationContext容器到類中)础废、LoadTimeWeaverAwareProcessor (織入Bean后置處理器)】
- 調(diào)用postProcessBeanFactory(beanFactory);留給子類來設(shè)置BeanFactory
- 調(diào)用invokeBeanFactoryPostProcessors(beanFactory) 方法
- 第一次調(diào)用已經(jīng)初始化過的 BeanDefinitionRegistryPostProcessor 類的 registryProcessor.postProcessBeanDefinitionRegistry(registry) 方法汛骂,基本上不會(huì)有,除非自己在前面步驟設(shè)置過
- 第二次調(diào)用實(shí)現(xiàn)了PriorityOrdered的 BeanDefinitionRegistryPostProcessor 接口的類的.postProcessBeanDefinitionRegistry(registry) 方法评腺,一般只會(huì)有 ConfigurationClassPostProcessor 類帘瞭,這個(gè)類在 1.a 步驟中被注冊(cè)成BeanDefinition
- ConfigurationClassPostProcessor 去解析配置類,如果類是由 @Configuration 注解的類蒿讥,則為 full 配置類蝶念,其他則為 lite 配置類【full配置類,會(huì)生成CGLib動(dòng)態(tài)代理芋绸,@Bean方法只會(huì)調(diào)用一次媒殉,下次就直接獲取上次的對(duì)象;Lite配置類摔敛,則生成普通類】
- 生成Configuration解析器廷蓉,會(huì)去解析 @ComponentScan 注解包下所有的類,并且會(huì)循環(huán)調(diào)用马昙,知道把所有需要解析成 BeanDefinition 的類都注冊(cè)進(jìn)來 (包括@Component苦酱、@Import、@ImportResource這些注解)
- 會(huì)解析配置類中有多個(gè)@Bean
- 調(diào)用實(shí)現(xiàn)了 Ordered 的 BeanDefinitionRegistryPostProcessor 接口的類 的 postProcessBeanDefinitionRegistry(registry) 方法
- 調(diào)用沒有實(shí)現(xiàn) PriorityOrdered给猾、Ordered 的 BeanDefinitionRegistryPostProcessor 接口的類 的 postProcessBeanDefinitionRegistry(registry) 方法
- 然后調(diào)用之前所有 BeanDefinitionRegistryPostProcessor 類的 postProcessBeanFactory(beanFactory) 方法疫萤,會(huì)調(diào)用 ConfigurationClassPostProcessor 類
- ConfigurationClassPostProcessor. postProcessBeanFactory(beanFactory) 會(huì)把Full配置類的BeanDefinition 的類型設(shè)置成CGLIB的動(dòng)態(tài)代理類型,初始化時(shí)敢伸,就是CGLIB動(dòng)態(tài)代理
- 調(diào)用實(shí)現(xiàn)了PriorityOrdered 的 BeanFactoryPostProcessor 類的 postProcessBeanFactory(beanFactory) 方法
- 調(diào)用實(shí)現(xiàn)了Ordered 的 BeanFactoryPostProcessor 類的 postProcessBeanFactory(beanFactory) 方法
- 調(diào)用沒有實(shí)現(xiàn) PriorityOrdered扯饶、Ordered 的 BeanFactoryPostProcessor 類的 postProcessBeanFactory(beanFactory) 方法
- EventListenerMethodProcessor (會(huì)在所有Bean都實(shí)例化完成后,解析Bean中是否帶有@EventListener方法,如果有尾序,則會(huì)利用EventListenerFactory钓丰,生成一個(gè)ApplicationListener放入容器中)默認(rèn)實(shí)例化出所有 EventListenerFactory 的類
- 調(diào)用registerBeanPostProcessors(beanFactory);注冊(cè)Bean的后置處理器到容器中
- 主要是兩個(gè)后置處理器 internalAutowiredAnnotationProcessor、internalCommonAnnotationProcessor
- 會(huì)按照優(yōu)先PriorityOrdered然后Ordered每币,最后都沒實(shí)現(xiàn)的BeanPostProcess類的順序放入到容器中
- 最后放入ApplicationListenerDetector
- 調(diào)用 initMessageSource(); 初始化國際化 携丁,一般是DelegatingMessageSource對(duì)象
- 調(diào)用 initApplicationEventMulticaster(); 設(shè)置容器的事件多播器為 SimpleApplicationEventMulticaster
- 調(diào)用 onRefresh(); 方法,Springboot 就是調(diào)用這個(gè)方法來啟動(dòng)tomcat容器的
- 調(diào)用registerListeners();注冊(cè)事件監(jiān)聽器到容器中兰怠,并且如果有早期事件類型梦鉴,則在容器事件廣播器未生成好之前發(fā)布事件
- 調(diào)用 finishBeanFactoryInitialization(beanFactory); 實(shí)例化非懶加載的 Bean
- 先判斷是否有conversionService類型的Bean,如果有揭保,則需要轉(zhuǎn)化生成
- 實(shí)例化LoadTimeWeaverAware對(duì)象
- 實(shí)例化Bean
- 實(shí)例化之前會(huì)先調(diào)用 InstantiationAwareBeanPostProcessor 接口的 postProcessBeforeInstantiation 方法肥橙,這個(gè)時(shí)候可以自己初始化出來,返回給容器
- 實(shí)例化對(duì)象秸侣,這個(gè)時(shí)候有個(gè)策略 getInstantiationStrategy().instantiate(mbd, beanName, this); 如果是之前設(shè)置了CGLIB動(dòng)態(tài)代理存筏,這里生成的是代理后的對(duì)象
- 遍歷調(diào)用MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()方法
- 這里會(huì)調(diào)用 AutowiredAnnotationBeanPostProcessor 的 postProcessMergedBeanDefinition 找到所有的 @Autowired或者@Value 注解的方法或?qū)傩裕瑸楹罄m(xù)IOC味榛,依賴注入做準(zhǔn)備
- 自動(dòng)注入屬性
- 生成后先遍歷所有的 BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName) 方法椭坚,這個(gè)方法可以重新返回一個(gè)新的Bean
- 所有的 Aware 拓展點(diǎn)在這里實(shí)現(xiàn),通過 ApplicationContextAwareProcessor 類搏色,實(shí)現(xiàn)了EnvironmentAware藕溅、EmbeddedValueResolverAware、ResourceLoaderAware继榆、ApplicationEventPublisherAware巾表、MessageSourceAware、ApplicationContextAware略吨、ApplicationStartupAware等類在這一步注入
- 實(shí)例化Bean集币,如果Bean實(shí)現(xiàn)了 InitializingBean 接口的Bean,會(huì)調(diào)用它的 afterPropertiesSet 方法
- 遍歷所有的 BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName) 方法翠忠,這個(gè)方法可以重新返回一個(gè)新的Bean
- 所有Bean實(shí)例化完成后 便利所有bean鞠苟,調(diào)用實(shí)現(xiàn)了 SmartInitializingSingleton 接口類的afterSingletonsInstantiated方法
- 最后調(diào)用 finishRefresh(),發(fā)布容器 publishEvent(new ContextRefreshedEvent(this)); 刷新完成事件
Spring所有拓展點(diǎn)以及順序
- 實(shí)現(xiàn)了 BeanDefinitionRegistryPostProcessor 接口的類秽之,調(diào)用 postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) 方法当娱,可以獲取到Bean定義的注冊(cè)器,去注冊(cè)BeanDefinition考榨,調(diào)用會(huì)按照先調(diào)用實(shí)現(xiàn)了 PriorityOrdered 接口 再調(diào)用 Ordered 接口 最后再調(diào)用沒有實(shí)現(xiàn) PriorityOrdered 接口 跨细、 Ordered 接口 的 BeanDefinitionRegistryPostProcessor 類
- 實(shí)現(xiàn)了 BeanFactoryPostProcessor 接口的類,調(diào)用 postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) 方法河质,可以獲取到Bean定義的注冊(cè)器冀惭,去注冊(cè)BeanDefinition震叙,調(diào)用會(huì)優(yōu)先調(diào)用實(shí)現(xiàn)了BeanDefinitionRegistryPostProcessor 接口的類的 postProcessBeanFactory方法,再按照先調(diào)用實(shí)現(xiàn)了 PriorityOrdered 接口 再調(diào)用 Ordered 接口 最后再調(diào)用沒有實(shí)現(xiàn) PriorityOrdered 接口 散休、 Ordered 接口 的 BeanDefinitionRegistryPostProcessor 類
- 實(shí)現(xiàn)了 InstantiationAwareBeanPostProcessor 接口的類媒楼,調(diào)用 postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 方法,這個(gè)方法可以直接自己初始化出來Bean
- 實(shí)現(xiàn)了 MergedBeanDefinitionPostProcessor 接口的類戚丸,調(diào)用 postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) 方法划址;這個(gè)時(shí)候Bean已經(jīng)初始化了,但是屬性還沒有注入限府;AutowiredAnnotationBeanPostProcessor 的 postProcessMergedBeanDefinition 找到所有的 @Autowired或者@Value 注解的方法或?qū)傩远岵瑸楹罄m(xù)IOC,依賴注入做準(zhǔn)備
- 實(shí)現(xiàn)了EnvironmentAware谣殊、EmbeddedValueResolverAware、ResourceLoaderAware牺弄、ApplicationEventPublisherAware姻几、MessageSourceAware、ApplicationContextAware势告、ApplicationStartupAware的類蛇捌,會(huì)在這一步注入相關(guān)環(huán)境變量屬性
- 實(shí)現(xiàn)了 BeanPostProcessor 接口的類,調(diào)用 postProcessBeforeInitialization(Object bean, String beanName) 方法咱台,這一步Bean已經(jīng)實(shí)例化了络拌,并且屬性已經(jīng)注入了,也可以通過這個(gè)拓展來修改對(duì)象
- 實(shí)現(xiàn)了 InitializingBean 接口的Bean回溺,會(huì)調(diào)用對(duì)象的 afterSingletonsInstantiated() 方法春贸。一般作為對(duì)象初始化完成調(diào)用的拓展點(diǎn)
- 實(shí)現(xiàn)了 BeanPostProcessor 接口的類,調(diào)用 postProcessAfterInitialization(Object bean, String beanName) 方法遗遵,這一步Bean已經(jīng)實(shí)例化了萍恕,并且屬性已經(jīng)注入了,也可以通過這個(gè)拓展來修改對(duì)象
- 調(diào)用實(shí)現(xiàn)了 SmartInitializingSingleton 接口類的 afterSingletonsInstantiated() 方法车要;這個(gè)時(shí)候所有的Bean已經(jīng)實(shí)例化完成允粤,后續(xù)加入的Bean不會(huì)受Bean工廠的后置處理器影響
- 監(jiān)聽Spring容器啟動(dòng)事件 ContextRefreshedEvent