//实现父类抽象的载入bean定义方法 @Override protectedvoidloadBeanDefinitions(DefaultListableBeanFactory beanFactory)throws BeansException, IOException { //创建XmlBeanDefinitionReader,即创建Bean读取器,并通过回调设置到容器中去,容器使用读取器读取Bean定义资源 // Create a new XmlBeanDefinitionReader for the given BeanFactory. XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// 为Bean读取器设置Spring资源加载器,AbstractXmlApplicationContext的祖先父类AbstractApplicationContext继承DefaultResourceLoader,因此,容器本身也是一个资源加载器 // Configure the bean definition reader with this context's // resource loading environment. beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this);
//当Bean读取器读取Bean定义的xml资源文件时,启用xml的校验机制 // Allow a subclass to provide custom initialization of the reader, // then proceed with actually loading the bean definitions. initBeanDefinitionReader(beanDefinitionReader); //Bean读取器真正实现加载的方法 loadBeanDefinitions(beanDefinitionReader); }
//这里是载入XML形式Bean定义资源文件方法 publicintloadBeanDefinitions(EncodedResource encodedResource)throws BeanDefinitionStoreException { Assert.notNull(encodedResource, "EncodedResource must not be null"); if (logger.isInfoEnabled()) { logger.info("Loading XML bean definitions from " + encodedResource); }
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get(); if (currentResources == null) { currentResources = new HashSet<>(4); this.resourcesCurrentlyBeingLoaded.set(currentResources); } if (!currentResources.add(encodedResource)) { thrownew BeanDefinitionStoreException( "Detected cyclic loading of " + encodedResource + " - check your import definitions!"); } try { //将资源文件转为InputStream的IO流 InputStream inputStream = encodedResource.getResource().getInputStream(); try { //从InputStream中得到XML的解析源 InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } //这里是具体的读取过程 return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } finally { //关闭充Resource中得到的IO流 inputStream.close(); } } catch (IOException ex) { thrownew BeanDefinitionStoreException( "IOException parsing XML document from " + encodedResource.getResource(), ex); } finally { currentResources.remove(encodedResource); if (currentResources.isEmpty()) { this.resourcesCurrentlyBeingLoaded.remove(); } } }