工作來幾乎所有的項目都用到了spring,卻一直沒有系統的讀下源碼,從頭開始系統的讀下吧,分章也不那么明確,讀到哪里記到哪里,僅僅作為個筆記吧。
先看ClassPathXmlApplicationContext的類圖
有人說:BeanFactory是Spring的心臟,ApplicationContext就是完整的軀體。ApplicationContext繼承了BeanFactory,ResourceLoader提供了類的管理以及資源的加載,同時又繼承了EnvironmentCapable,MessageSource, ApplicationEventPublisher等,將環境、消息、事件等統一管理,真是的算上一個完整的軀干了。
簡單使用:
ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:META-INF/spring/test-spring.xml"); User user = context.getBean(User.class); System.out.println(user.getId());
ApplicationContext的初始化時序圖如下:
1、super(parent)調用父類構造函數,在AbstractApplicationContext中會初始化resourcePatternResolver。
2、setConfigLocations(configLocations)解析spring的配置文件地址,設置到configLocations。
3、refresh()這是ApplicationContext初始化的核心,會在這里初始化BeanFactory,解析XML加載BeanDefinition,注冊bean處理器,注冊事件添加監聽等
3.1 prepareRefresh(),初始化基礎屬性值
3.2 obtainFreshBeanFactory(),這里會再執行refreshBeanFactory時候創建一個默認的BeanFactory:DefaultListableBeanFactory,並加載BeanDefinition。
加載BeanDefinition是會創建一個XmlBeanDefinitionReader對象,交由XmlBeanDefinitionReader去進行加載。這里處理的比較復雜后面單獨分析下XmlBeanDefinitionReader。
3.3 prepareBeanFactory(beanFactory),為beanFactory設置一些屬性如ClassLoader,BeanExpressionResolver,PropertyEditorRegistrar,BeanPostProcessor等
3.4 invokeBeanFactoryPostProcessors(beanFactory),為beanFactory注冊BeanFactoryPostProcessor
3.5 registerBeanPostProcessors(beanFactory),注冊當Bean創建時候的BeanPostProcessor
3.6 initMessageSource()初始化上下文的消息源:DelegatingMessageSource
3.7 initApplicationEventMulticaster()初始化了一個事件傳播器:SimpleApplicationEventMulticaster
3.8 registerListeners()獲取ApplicationListener,並在事件傳播器中注冊他們
3.9 finishBeanFactoryInitialization(beanFactory),獲取LoadTimeWeaverAware並初始化他們,初始化單例並且非懶加載的Bean
3.10 finishRefresh()完成refresh Context操作,初始化LifecycleProcessor並start,發布ContextRefreshedEvent事件
3.11 resetCommonCaches()主要是清理緩存
一個ClassPathXmlApplicationContext的初始化過程基本如上,詳細的BeanDefinition加載過程,獲取Bean操作后續再寫吧。