ClassPathXmlApplicationContext继承了AbstractXmlApplicationContext,实现了ApplicationContext接口。BeanFactory是全部容器的顶级接口,spring中全部容器都是基于BeanFactory的。ClassPathXmlApplicationContext继承关系以下图:spring
ClassPathXmlApplicationContext中有多个构造方法,最终都经过以下的构造方法初始化容器:post
public ClassPathXmlApplicationContext( String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); } }
其中,refresh()方法完成了容器的初始化。this
refresh()方法的实现代码以下spa
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 上下文刷新的准备工做,完成一下工做: //一、设置启动时间、是否关闭和是否激活 //二、在上下文中初始化任何占位符属性资源 //三、验证标记为必需的属性文件是可解析的 prepareRefresh(); // 建立DefaultListableBeanFactory实例,解析xml配置文件,注册bean ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //对BeanFactory进行各类功能填充 //在此方法中,增长的支持@Qualifier与@Autowired这两个注解 prepareBeanFactory(beanFactory); try { // 由子类实现,可进行自定义扩展 postProcessBeanFactory(beanFactory); // 激活BeanFactory的处理器 invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // 初始化message资源 initMessageSource(); // 为这个context初始化一个事件广播器 initApplicationEventMulticaster(); // 由子类实现,初始化其余bean onRefresh(); // 注册已实现ApplicationListener接口的Bean registerListeners(); // 实例化全部非延迟初始化的单例模式bean finishBeanFactoryInitialization(beanFactory); // 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知监听者 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(); } } }
此方法主要做用是建立DefaultListableBeanFactory实例,解析xml配置文件,注册bean。内部调用了调用了AbstractRefreshableApplicationContext类的refreshBeanFactory()方法建立bean工厂。refreshBeanFactory()方法实现以下:code
protected final void refreshBeanFactory() throws BeansException { //若是beanfactory存在,销毁因此bean和关闭beanfactory if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { //定义beanFactory DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); //将bean解析为BeanDefinition loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
refreshBeanFactory()方法中,首先判断是否存在beanfactory,若是存在,销毁全部Bean,关闭beanfactory。createBeanFactory()方法建立一个新的容器。在本方法中,最重要的是loadBeanDefinitions(beanFactory),调用这个方法解析xml配置文件,注册bean。xml
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // 根据给定的BeanFactory建立一个新的 XmlBeanDefinitionReader XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // 根据上下文配置bean definition reader beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); initBeanDefinitionReader(beanDefinitionReader); //经过beanDefinitionReader解析xml配置文件,注册bean loadBeanDefinitions(beanDefinitionReader); }
在XmlBeanDefinitionReader中实现了loadBeanDefinitions(beanDefinitionReader)方法,代码以下:blog
//省略了异常处理相关代码,主要逻辑以下 public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { //从encodedResource中获得InputSource和Resource Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get(); InputStream inputStream = encodedResource.getResource().getInputStream(); InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } //调用此方法加载BeanDefinition return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); }
doLoadBeanDefinitions(inputSource, encodedResource.getResource())中,从资源文件中读取Document,而且调用registerBeanDefinitions(doc, resource)注册BeanDefinition,省略无关代码,实现以下:继承
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { //从resource中读取获得Document Document doc = doLoadDocument(inputSource, resource); //注册BeanDefinition return registerBeanDefinitions(doc, resource); } catch (BeanDefinitionStoreException ex) { throw ex; } }
在registerBeanDefinitions(doc, resource)方法中,BeanDefinition的注册时委托给BeanDefinitionDocumentReader的registerBeanDefinitions(doc, createReaderContext(resource))方法进行注册的。接口