XmlBeanDefinitionReader 中 loadBeanDefinitions 方法是在 org.springframework.beans.factory.support.BeanDefinitionReader 接口中被定义的,其作用是从资源文件中加载 bean 定义,该方法接收一个 org.springframework.core.io.Resource 类型的参数,返回值是 int 类型的,从资源文件中成功加载并注册成功的 bean 定义数量,当加载或解析 bean 定义时出现错误会抛出 org.springframework.beans.factory.BeanDefinitionStoreException 异常。
源码
int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;
loadBeanDefinitions 方法在 org.springframework.beans.factory.xml.XmlBeanDefinitionReader 中的实现
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(new EncodedResource(resource));
}
loadBeanDefinitions(EncodedResource encodedResource) 方法实现
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Loading XML bean definitions from " + encodedResource);
}
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
// 重点方法
// 执行 bean 定义的加载
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
doLoadBeanDefinitions(InputSource inputSource, Resource resource) 方法实现
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
// 将 XML 文件转换成 Document 对象
Document doc = doLoadDocument(inputSource, resource);
// 解析 bean 定义,并注册到 bean 工厂
int count = registerBeanDefinitions(doc, resource);
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
}
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);
}
}
doLoadDocument(InputSource inputSource, Resource resource) 方法实现
protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
getValidationModeForResource(resource), isNamespaceAware());
}
registerBeanDefinitions(Document doc, Resource resource) 方法实现
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
// 创建一个 BeanDefinitionDocumentReader 实例
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
// 获取 bean 工厂中现有的 bean 定义个数
int countBefore = getRegistry().getBeanDefinitionCount();
// 解析资源文件中包含的 bean 定义并注册到 bean 工厂中
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
// 返回本次加载的 bean 定义个数
return getRegistry().getBeanDefinitionCount() - countBefore;
}
XmlBeanDefinitionReader 中 loadBeanDefinitions 方法讲解完毕,你是否对 Spring 有了新的认识了?