protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); //从这块代码
可以发现XML的解析估计是在这里发生的,也就是这个Reader来读取的,
....
loadBeanDefinitions(beanDefinitionReader);
}
….
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources); //果然是由Reader来加载和解析XML并载入BeanDefinition中的!
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
int validationMode = getValidationModeForResource(resource);
Document doc = this.documentLoader.loadDocument(
inputSource, getEntityResolver(), this.errorHandler, validationMode, isNamespaceAware());
//在这里激发注册过程
return registerBeanDefinitions(doc, resource);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (SAXParseException ex) {
…
}
从上上面的代码中,你可以肯定的是 XML 是在 XmlBeanDefinitionReader 类中解析的,解析到 BeanDefinition 中!进入 XmlBeanDefinitionReader 中,看一看:
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<EncodedResource>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
//这里是具体加载的实现逻辑
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
......
}
哈哈,你也可以看到 ReaourceLoader 确实是加载 XML 的!进入 doLoadBeanDefinitions 方法!
-------------TODO,这里需要补充一下
--------------------------------------------------------------------------------------------------------
看到了吧?就是一个大家经常用到 SAX 的 Document 来取得 XML 文档的,在进入 registerBeanDefinitions 看看!
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
if (documentReader instanceof DefaultBeanDefinitionDocumentReader) {
((DefaultBeanDefinitionDocumentReader)documentReader).setEnvironment(this.getEnvironment());
}
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));//在这里注册,也就是注册到一个共享的容器中,比如Map.这样缓存起来后,spring其他部分就可以从一个共享的位置加载目标BeanDefinition了(通过BeanDefinition的名字)。
return getRegistry().getBeanDefinitionCount() - countBefore;
}
在进入 documentReader.registerBeanDefinitions 看看!
protected void doRegisterBeanDefinitions(Element root) {
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
boolean isCandidate = false;
if (profileSpec == null || profileSpec.equals("")) {
isCandidate = true;
} else {
String[] profiles = commaDelimitedListToStringArray(trimAllWhitespace(profileSpec));
for (String profile : profiles) {
if (this.environment.getActiveProfiles().contains(profile)) {
isCandidate = true;
break;
}
}
}
if (!isCandidate) {
return;
}
BeanDefinitionParserDelegate parent = this.delegate;//Deletgate里面包含着多有XML属性和elemnt的结构信息
this.delegate = createHelper(readerContext, root, parent);
preProcessXml(root);
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);