Spring的啟動(dòng)過程
本文的目的是記錄自己在學(xué)習(xí)Spring容器啟動(dòng)過程中的一些筆記寝受,以供后面復(fù)習(xí)柬甥,也希望可以給有需要的朋友提供一點(diǎn)幫助。本次分析所用的Spring版本為 5.1.4.RELEASE辽话。
首先我們從容器創(chuàng)建為入口扔役,逐漸深入容器的啟動(dòng)過程帆喇。
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
上面這行代碼大家應(yīng)該都很熟悉,通過這行代碼就可以完成IOC容器的初始化亿胸,讓Spring幫我們管理一切坯钦。下面我們就從AnnotationConfigApplicationContext這個(gè)類開始,一層一層解開Spring的神秘面紗侈玄。
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
/**
此處只是初始化了Bean Definition的reader和scanner
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
*/
this();
// 此處只是將傳進(jìn)來的配置類(AppConfig.class注冊(cè)到BeanDefinitionMap中去)
register(annotatedClasses);
// 重點(diǎn)在refresh方法里面
refresh();
}
在前兩個(gè)方法中只是做了簡(jiǎn)單的初始化ioc容器所需的對(duì)象婉刀,此時(shí)ioc容器是空的,通過refresh方法會(huì)一次來解析beandefinition并產(chǎn)生對(duì)象裝入容器中拗馒,下面來分析refresh方法路星。
// Prepare this context for refreshing.
// 這個(gè)方法只是記錄了容器啟動(dòng)時(shí)間,設(shè)置容器為active狀態(tài),并無實(shí)際操作洋丐,不重要呈昔。
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 此處只是給Bean Factory設(shè)置了一個(gè)SerializationId
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 初始化了IOC容器的一些工具,比如Class Loader友绝、EL表達(dá)式解析器和屬性解析器
prepareBeanFactory(beanFactory);
// Allows post-processing of the bean factory in context subclasses.
// 空方法
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 執(zhí)行所有的BeanFactoryPostProcessor
// 在ConfigurationClassPostProcessor#processConfigBeanDefinitions()方法會(huì)對(duì)所有的配置類進(jìn)行處理堤尾,通過ConfigurationClassParser對(duì)象來解析,最終通過parser.parse(candidates);來調(diào)用解析方法迁客。
// 其中會(huì)處理所有@Configuration注解的類郭宝,解析其配置的@Bean和@ComponentScan注解,將相關(guān)的Bean掃描并加入到BeanDefinitionMaps中掷漱,之后會(huì)使用動(dòng)態(tài)代理(CGLIB)增強(qiáng)Configuration類粘室,增強(qiáng)是直接修改Bean Definition中BeanClass屬性,直接替換為代理后的class
invokeBeanFactoryPostProcessors(beanFactory);
// 注冊(cè)了兩個(gè)BeanPostProcessor卜范,一個(gè)CommonBeanPostProcessor衔统,另一個(gè)AutoWiredBeanPostProcessor,注意,這個(gè)后置處理器很重要海雪,他是完成自動(dòng)裝配的關(guān)鍵锦爵!
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 像BeanFactory注冊(cè)了messageSource
initMessageSource();
// Initialize event multicaster for this context.
// 向BeanFactory注冊(cè)了applicationEventMulticaster
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 空方法,api注釋中寫的是允許子類添加一些特定的邏輯在實(shí)例化單例Bean之前奥裸。 before instantiation of singletons.
onRefresh();
// Check for listener beans and register them.
// 將實(shí)現(xiàn)了ApplicationListener的類注冊(cè)到applicationEventMulticaster中
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 實(shí)例化Bean DefinitionMap中所有的非懶加載的單例Bean
// 前面做大堆準(zhǔn)備工作险掀,最終會(huì)凍結(jié)配置,防止配置發(fā)生變化(freezeConfiguration)湾宙,結(jié)束后調(diào)用preInstantiateSingletons()方法來實(shí)例化樟氢,由于實(shí)例化較為重要,下面單獨(dú)分析preInstantiateSingletons方法
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 結(jié)束啟動(dòng)過程创倔,會(huì)清空在初始化過程中創(chuàng)建的一些緩存嗡害,同時(shí)調(diào)用LifecycleProcessor#onRefresh方法。最后會(huì)發(fā)布ContextRefreshedEvent事件畦攘。
finishRefresh();
以上就是Spring啟動(dòng)的全過程,后面我們會(huì)深入分析容器的初始化過程十电,容器如何解析配置類知押,如何根據(jù)配置類來實(shí)例化單例對(duì)象等。
由于本人水平有限鹃骂,難免遇到表述不清或錯(cuò)誤的情況台盯,如果存在任何問題,請(qǐng)大家及時(shí)提醒畏线,我會(huì)在第一時(shí)間進(jìn)行修正静盅。