java程序入口
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
web程序入口
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener>
注意:不管上面哪種方式,最終都會調AbstractApplicationContext的refresh方法
,而這個方法才是我們真正的入口。
流程解析
- AbstractApplicationContext的
refresh
方法
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. // STEP 1: 刷新預處理 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. // STEP 2: // a) 創建IoC容器(DefaultListableBeanFactory) // b) 加載解析XML文件(最終存儲到Document對象中) // c) 讀取Document對象,並完成BeanDefinition的加載和注冊工作 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. // STEP 3: 對IoC容器進行一些預處理(設置一些公共屬性) prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. // STEP 4: postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. // STEP 5: 調用BeanFactoryPostProcessor后置處理器對BeanDefinition處理 invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // STEP 6: 注冊BeanPostProcessor后置處理器 registerBeanPostProcessors(beanFactory); // Initialize message source for this context. // STEP 7: 初始化一些消息源(比如處理國際化的i18n等消息源) initMessageSource(); // Initialize event multicaster for this context. // STEP 8: 初始化應用事件廣播器 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // STEP 9: 初始化一些特殊的bean onRefresh(); // Check for listener beans and register them. // STEP 10: 注冊一些監聽器 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. // STEP 11: 實例化剩余的單例bean(非懶加載方式) // 注意事項:Bean的IoC、DI和AOP都是發生在此步驟 finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. // STEP 12: 完成刷新時,需要發布對應的事件 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(); } } }