前面说到的是XmlBeanDefinitionReader阅读器中的父类对loadBenaDefinition的规范
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
//就是说明resource资源的定位必须为非空的
Assert.notNull(resources, "Resource array must not be null");
int count = 0;
Resource[] var3 = resources;
int var4 = resources.length;
for(int var5 = 0; var5 < var4; ++var5) {
Resource resource = var3[var5];
count += this.loadBeanDefinitions((Resource)resource);
}
return count;
}
//注意这个loadBeanDefinitions是一个抽象方法,它是没有实现的,具体的实现在其子类XmlBeanDefinitionReader中
在读取器中需要得到Resource,因为这个resource对象中封装了XML文件的I/O操作,所以阅读器需要的到Resource对象得到XMl中的文件对象
在的到Resource对象之后可以按照Spring的Bean定义规则对这个XML的文档树进行解析了
第二部分:利用BeanDefinitionParserDelegate来完成对文档树的解析工作,
下面的代码讲述的就是BeanDefinition的载入
//载入xml的Resource资源
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loading XML bean definitions from " + encodedResource);
}
Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!((Set)currentResources).add(encodedResource)) {
throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
} else {
int var5;
try {
//这里的到Xml的resource,并且得到Io中InoutStream对象
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
//记住doloadBeanDefinitons这个方法
var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
} finally {
inputStream.close();
}
} catch (IOException var15) {
throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var15);
} finally {
((Set)currentResources).remove(encodedResource);
if (((Set)currentResources).isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
return var5;
}
}
下面这个部分是对doLoadBeanDefinitions方法的解析
代码解析如下:
//具体的
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
try {
//这里有必要对它进行标识,是调用doLoadDocument来对resource进行调用,这个doLoadDopcument是指代DefaultLoader
Document doc = this.doLoadDocument(inputSource, resource);
//到这一步就时调用Spring中规范
int count = this.registerBeanDefinitions(doc, resource);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
} catch (BeanDefinitionStoreException var5) {
throw var5;
} catch (SAXParseException var6) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var6.getLineNumber() + " in XML document from " + resource + " is invalid", var6);
} catch (SAXException var7) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var7);
} catch (ParserConfigurationException var8) {
throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var8);
} catch (IOException var9) {
throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var9);
} catch (Throwable var10) {
throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var10);
}
}
再下面的就是分析怎样将BeanFacotory进行转化成容器内部的数据结构的,也就是对registBeanDefinitions这个方法的分析了,具体的源码实现是在BeanDefinitionDocumentReader中完成的
实际的代码如下:
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
//得到BeanDefinitionDocumentReader来对XML的BeanDefinition进行分析
BeanDefinitionDocumentReader documentReader =this.createBeanDefinitionDocumentReader();
//记录注册之前的次数
int countBefore = this.getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
return this.getRegistry().getBeanDefinitionCount() - countBefore;
}
是对上面的代码解析:BeanDefinition载入是分为两个部分的
1:调用xml的解析器得到document对象,这些document不是按照spring规则解析的
2:按照xml解析器解析过后的,就需要按照spring的Bean规则对其进行解析
具体的解析地方是在:documentReader中进行的(DefaultBeanDefinitionDoucmentReader)
3:然后调用BeanDefinition的处理,处理的结果被BeanDefintiionHolder的对象所持有
在这个BeanDefinitionHolder中存储的信息数据主要有Bean的名字,别名集合等
4:然后就是对BeanDefinition进行所谓的解析
主要是通过对Document文档树的内容进行解析来完成 -BeanDefintiionParserDelegate进行解析实现