在測試時,經常使用這種方式來創建spring容器
//創建基於注解的springIOC容器 ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AopBeanConfig.class); //創建基於配置文件的springIOC容器 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-beans.xml");
無論哪種方式,最終都會調用AbstractApplicationContext的一個重要方法——refresh(),首先來看這個方法的spring源碼
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 1. Prepare this context for refreshing. prepareRefresh(); // 2. Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 3. Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // 4. Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // 5. Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // 6. Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // 7. Initialize message source for this context. initMessageSource(); // 8. Initialize event multicaster for this context. initApplicationEventMulticaster(); // 9. Initialize other special beans in specific context subclasses. onRefresh(); // 10. Check for listener beans and register them. registerListeners(); // 11. Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // 12. Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
重點步驟簡析
1. prepareRefresh 准備刷新容器
(1) initPropertySources() 自定義屬性設置,空方法,留給子類繼承
(2) getEnvironment.validateRequiredProperties 首先獲取環境配置,然后校驗必需屬性
(3) this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
初始化事件監聽器
(4) this.earlyApplicationEvents = new LinkedHashSet<>(); 初始化早期事件
2. obtainFreshBeanFactory 獲取組件工廠
(1) refreshBeanFactory 新建一個組件工廠,類型為DefaultListableBeanFactory,
然后對這個組件工廠設置了一個序列化ID
(2) getBeanFactory 返回剛剛創建的組件工廠
3. prepareBeanFactory 對組件工廠做各種預處理設置
(1) 在組件工廠中設置類加載器、屬性解析器等
(2) 在組件工廠中添加部分組件后置處理器,例如ApplicationContextAwareProcessor、ApplicationListenerDetector
(3) 在組件工廠中設置忽略自動注入的接口
(4) 設置自動裝配規則
(5) 在組件工廠中注冊一些組件,例如環境配置ConfigurableEnvironment
4. postProcessBeanFactory 組件工廠的后置處理工作
5. invokeBeanFactoryPostProcessors 執行組件工廠后置處理器
這一步是在組件工廠的標准初始化(1-4)之后進行的,主要是執行BeanFactoryPostProcessor及其子接口的
BeanFactoryPostProcessor的子接口主要是指BeanDefinitionRegistryPostProcessor,可以向容器中注冊新的組件,這個接口的特點是有兩個方法,一個是自身的postProcessBeanDefinitionRegistry,另一個繼承自BeanFactoryPostProcessor的postProcessBeanFactory,從源碼可以看出,spring會先執行BeanDefinitionRegistryPostProcessor類型的組件的自身方法,然后執行其繼承方法,最后才調用非BeanDefinitionRegistryPostProcessor的BeanFactoryPostProcessor的后置處理方法
(1) 從容器器中獲取BeanDefinitionRegistryPostProcessor類型的組件
(2) 將BeanDefinitionRegistryPostProcessor類型的組件按照順序分類並排序,即是否實現了PriorityOrdered、Ordered接口
(3) 依次執行實現了PriorityOrdered接口的、實現了Ordered接口的、沒有實現任何順序接口的組件的postProcessBeanDefinitionRegistry方法
(4) 執行所有BeanDefinitionRegistryPostProcessor組件的postProcessBeanFactory方法
(5) 從容器中獲取其他的BeanFactoryPostProcessor類型的組件,即不是BeanDefinitionRegistryPostProcessor類型的
(6) 剩下的步驟跟上面類似,就是先按照實現的順序接口分類,在每個類別下排序,然后依次執行它們的postProcessBeanFactory方法
6. registerBeanPostProcessors 注冊組件后置處理器,這種處理器用於攔截bean的創建過程
beanPostProcessor有很多子接口,每種子接口的執行時機各有不同
|-DestructionAwareBeanPostProcessor
|-InstantiationAwareBeanPostProcessor
|-MergedBeanDefinitionPostProcessor
|-SmartInstantiationAwareBeanPostProcessor
(1) 獲取所有的beanPostProcessor的組件名
(2) 將所有的組件按優先順序分為三類:
|-實現了PriorityOrdered接口的列表priorityOrderedPostProcessors
|-實現了Ordered接口的列表orderedPostProcessors
|-沒有實現任何順序接口的列表nonOrderedPostProcessors
還有一種特殊情況,凡是MergedBeanDefinitionPostProcessor類型的,都放在internalPostProcessors中
(3) 注冊priorityOrderedPostProcessors
(4) 注冊orderedPostProcessors
(5) 注冊nonOrderedPostProcessors
(6) 注冊internalPostProcessors
(7) 注冊ApplicationListenerDetector,它的作用是在組件初始化之后判斷其是否為
ApplicationListner類型,如果是,則將其添加進容器的監聽器集合
7. initMessageSource 初始化消息源組件,用於消息綁定、消息解析等功能,並且提供國際化解決方案
(1) 獲取beanFactory
(2) 判斷beanFactory中是否包含id為messageSource的組件
(3) 如果已存在,則賦值給容器的messageSource屬性,這種情況是我們自己在容器中注冊了這個組件
(4) 如果不存在,則新建一個DelegatingMessageSource,並賦值給容器的messageSource屬性,
然后在beanFactory中注冊這個新組件,並設置其id為messageSource
8. initApplicationEventMulticaster 初始化事件廣播器
(1) 獲取beanFactory
(2) 判斷beanFactory中是否存在id為applicationEventMulticaster的組件
(3) 如果已存在,則賦值給容器的applicationEventMulticaster屬性,這種情況是我們自己在容器中注冊了這個組件
(4) 如果不存在,則新建一個SimpleApplicationEventMulticaster,並賦值給容器的
applicationEventMulticaster屬性,然后在beanFactory中注冊這個新組件,
並設置其id為applicationEventMulticaster
9. onRefresh 沒有任何操作,留給子類繼承的,我們可以自定義子容器,在重寫方法中做一些我們想要的操作
10. registerListeners 注冊事件監聽器
(1) 獲取容器的屬性applicationListeners,這是一個事件監聽器的集合,將集合中的每個元素都添加進事件廣播器
(2) 從容器中獲取所有ApplicationListener類型的組件,將這些組件添加進事件廣播器
(3) 發布早期事件,即容器的earlyApplicationEvents屬性(參考第1(4)步),然后清空早期事件
11. finishBeanFactoryInitialization 完成剩下的單實例bean的初始化
(1) 進入DefaultListableBeanFactory.preInstantiateSingletons方法,獲取容器中所有的組件id列表
(2) 遍歷組件id列表,對每個組件,獲取其組件定義信息,即RootBeanDefinition
(3) 從組件定義信息中篩選掉抽象類、非單實例、懶加載的,這些bean在創建容器時並不初始化,
另外還有工廠組件,即實現了FactoryBean接口的,需要另外一套邏輯進行初始化
(4) 從緩存中獲取單實例bean,即DefaultSingletonBeanRegistry類的singletonObjects屬性,所有被創建過的
單實例bean都會被緩存在這個映射中;如果緩存中存在,說明這個組件之前被創建過,直接返回
(5) 如果緩存中不存在,則開始新建
① 將組件標記為已創建,即將其id存入AbstractBeanFactory的alreadyCreated屬性中
② 獲取組件的定義信息,即RootBeanDefinition
③ 從定義信息中獲取該組件依賴的組件,如果存在,則重新從第11(4)步開始執行,創建這些依賴的組件
④ 創建完依賴組件(如果存在)之后,以下開始正式新建目標組件
⑤ 給組件后置處理器一個機會用代理對象代替目標對象,即執行InstantiationAwareBeanPostProcessor
類型的組件后置處理器的postProcessBeforeInstantiation、postProcessAfterInitialization方法
⑥ Allow post-processors to modify the merged bean definition,即執行
MergedBeanDefinitionPostProcessor類型組件后置處理器的postProcessMergedBeanDefinition方法
⑦ 執行AbstractAutowireCapableBeanFactory.populateBean方法,即屬性賦值
在屬性賦值之前,首先拿到InstantiationAwareBeanPostProcessor類型的組件后置處理器,
並執行postProcessAfterInstantiation、postProcessProperties、postProcessPropertyValues方法;
然后才執行該類的applyPropertyValues方法,利用反射調用組件的setter方法進行屬性賦值
⑧ 執行以下三種aware接口的方法:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
⑨ 執行組件后置處理器的初始化前方法,即BeanPostProcessor.postProcessBeforeInitialization
⑩ 執行組件的初始化方法,即InitializingBean.afterPropertiesSet,以及在容器中自定義的initMethod
⑪ 執行組件后置處理器的初始化后方法,即BeanPostProcessor.postProcessAfterInitialization
⑫ 如果需要,注冊組件的銷毀方法,例如DisposableBean.destroy,以及在容器中自定義的destroyMethod
這里只是注冊,並不調用
(6) 通過第11(5)步,單實例bean已經創建並初始化完成,接着,會調用AbstractBeanFactory的父類方法——
DefaultSingletonBeanRegistry.getSingleton方法,將新建的bean存入singletonObjects屬性中,即緩存
(7) 回到DefaultListableBeanFactory.preInstantiateSingletons方法(見第11(1)步)
如果新建的bean實現了SmartInitializingSingleton接口,則執行afterSingletonsInstantiated回調方法
12. finishRefresh 完成容器刷新
(1) 初始化生命周期處理器(LifecycleProcessor),先從BeanFactory中按類型獲取,
如果沒有就新建一個DefaultLifecycleProcessor,並注冊進BeanFactory
(2) 獲取上一步注冊的生命周期處理器,回調其onRefresh方法
(3) 發布容器刷新事件,即ContextRefreshedEvent
