WebApplicationContext的三個(gè)實(shí)現(xiàn)類:XMLWebApplicationContext缘屹、GroovyWebApplicationContext和AnnotationConfigWebApplicationContext卡者。
應(yīng)用上下文的初始化
XmlWebApplcationContext
XmlWebApplcationContext是傳統(tǒng)的基于xml的Bean的定義。
web.xml中我們會(huì)添加一個(gè)ContextLoaderListener的listener从隆,首先它實(shí)現(xiàn)了ServletContextListener接口,可以接收上下文初始化完成和銷毀的事件缭裆。同時(shí)ContextLoaderListener還繼承了ContextLoader類键闺,從介紹來(lái)看ContextLoader的作用是執(zhí)行根應(yīng)用上下文的初始化工作。
初始化WebApplicationContext
監(jiān)聽(tīng)器接收到ServletContext初始化完成的事件后澈驼,就由ContextLoader開(kāi)始初始化WebApplicationContext:首先從ServletContext中查找是否有自定義的contextClass辛燥,如未找到則使用默認(rèn)策略(spring-web包中的ContextLoader.properties), XmlWebApplicationContext的完整路徑就配置在其中;然后加載上下文類型的class,并初始化挎塌。
為根應(yīng)用上下文添加父上下文
對(duì)于純web應(yīng)用來(lái)說(shuō)徘六,其根應(yīng)用上下文的父上下文為NULL。
刷新根應(yīng)用上下文
- 將ServletContext關(guān)聯(lián)給根應(yīng)用上下文榴都;
- 將contextConfigLocation的值記錄到根應(yīng)用上下文待锈;
初始化PropertySource(分別從servletContextInitParams、servletConfigInitParams嘴高、jndiProperties竿音、systemProperties、systemEnvironment中加載)拴驮,且該動(dòng)作在每次上下文刷新的時(shí)候都會(huì)執(zhí)行一次春瞬。
個(gè)性化上下文:從ServletContext的初始化參數(shù)中查找globalInitializerClasses和contextInitializerClasses,并對(duì)initializer進(jìn)行排序套啤,然后依次初始化根應(yīng)用上下文宽气。
-
根應(yīng)用上下文執(zhí)行刷新動(dòng)作
準(zhǔn)備工作:將上下文設(shè)置為已生效;初始化PropertySource等
刷新BeanFactory:清空bean并關(guān)閉BeanFactory(置為NULL)潜沦,然后創(chuàng)建新的并配置BeanFactory(DefaultListableBeanFactory)抹竹,如是否允許同名bean覆蓋就的bean、是否允許bean之間的循環(huán)引用止潮。之后就會(huì)加載BeanDefinition窃判,慢慢接近我們的主題。
-
準(zhǔn)備BeanFactory:
- 配置bean初始化后的處理(BeanPostProcessor)
- 注冊(cè)ResolveableDependency
- 檢查是否有bean需要load-time-waving喇闸,若有為BeanFactory添加BeanPostProcessor--LoadTimeWeaverAwareProcessor
- 注冊(cè)默認(rèn)environment bean
// Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFa // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFa // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFa // Initialize message source for this context. initMessageSo // Initialize event multicaster for this context. initApplicationEventMultica // Initialize other special beans in specific context subclasses. onRef // Check for listener beans and register them. registerListe // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFa // Last step: publish corresponding event. finishRefresh();
為ServletContext添加新的屬性
屬性值為根應(yīng)用上下文袄琳。
加載BeanDefinition
為BeanFactory新建XmlBeanDefinitionReader,加載并從Root開(kāi)始解析xml配置文件燃乍,并遍歷各級(jí)的節(jié)點(diǎn)唆樊。節(jié)點(diǎn)的類型可以有:import、alias刻蟹、bean和beans逗旁。根據(jù)類型的不同的處理,最后都會(huì)集中在處理bean類型的節(jié)點(diǎn)舆瘪。將bean節(jié)點(diǎn)映射成BeanDefinitionHolder片效,并在BeanFactory中注冊(cè),key為bean的name英古,valude為BeanDefinition對(duì)象淀衣。由BeanFactory的ConcurrentHashMap類型的成員變量持有。
注冊(cè)完成后召调,發(fā)出組件注冊(cè)事件膨桥,并創(chuàng)建BeanComponentDefinition對(duì)象蛮浑。改對(duì)象持有改bean內(nèi)部bean的定義和外部bean的引用(BeanReference)