基於Xml 的IOC 容器-開始讀取配置內容

Leon_Jinhai_Sun發表於2020-11-14

繼續回到XmlBeanDefinitionReader 的loadBeanDefinitions(Resource …)方法看到代表bean 檔案的資源定義以後的載入過程。

//XmlBeanDefinitionReader載入資源的入口方法
@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
	//將讀入的XML資源進行特殊編碼處理
	return loadBeanDefinitions(new EncodedResource(resource));
}

//這裡是載入XML形式Bean定義資原始檔方法
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
	Assert.notNull(encodedResource, "EncodedResource must not be null");
	if (logger.isInfoEnabled()) {
		logger.info("Loading XML bean definitions from " + encodedResource.getResource());
	}

	Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
	if (currentResources == null) {
		currentResources = new HashSet<>(4);
		this.resourcesCurrentlyBeingLoaded.set(currentResources);
	}
	if (!currentResources.add(encodedResource)) {
		throw new 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) {
		throw new BeanDefinitionStoreException(
				"IOException parsing XML document from " + encodedResource.getResource(), ex);
	}
	finally {
		currentResources.remove(encodedResource);
		if (currentResources.isEmpty()) {
			this.resourcesCurrentlyBeingLoaded.remove();
		}
	}
}
//從特定XML檔案中實際載入Bean定義資源的方法
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
		throws BeanDefinitionStoreException {
	try {
		//將XML檔案轉換為DOM物件,解析過程由documentLoader實現
		Document doc = doLoadDocument(inputSource, resource);
		//這裡是啟動對Bean定義解析的詳細過程,該解析過程會用到Spring的Bean配置規則
		return registerBeanDefinitions(doc, resource);
	}
	catch (BeanDefinitionStoreException ex) {
		throw ex;
	}
	catch (SAXParseException ex) {
		throw new XmlBeanDefinitionStoreException(resource.getDescription(),
				"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
	}
	catch (SAXException ex) {
		throw new XmlBeanDefinitionStoreException(resource.getDescription(),
				"XML document from " + resource + " is invalid", ex);
	}
	catch (ParserConfigurationException ex) {
		throw new BeanDefinitionStoreException(resource.getDescription(),
				"Parser configuration exception parsing XML from " + resource, ex);
	}
	catch (IOException ex) {
		throw new BeanDefinitionStoreException(resource.getDescription(),
				"IOException parsing XML document from " + resource, ex);
	}
	catch (Throwable ex) {
		throw new BeanDefinitionStoreException(resource.getDescription(),
				"Unexpected exception parsing XML document from " + resource, ex);
	}
}

通過原始碼分析,載入Bean 配置資訊的最後一步是將Bean 配置資訊轉換為Document 物件,該過程由documentLoader()方法實現。

 

 

相關文章