Spring-IoC容器初始化流程源码分析
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(); } } }