您的位置:首页 > 编程语言 > Java开发

Spring Ioc(4)——web中BeanDefinition的载入

2013-11-06 09:07 411 查看
我们继续上一节,其实spring Ioc的实现从宏观上看,分为三步:

(1)BeanDefinition的载入

(2)BeanDefinition的解析

(3)BeanDefinition的注册

1、BeanDefinition载入的入口
那么分别一个一个来分析,先从载入入手。BeanDefinition的载入,就相当于把我们定义的BeanDefinition在IOC容器中表示成spring内部的数据结构的过程,BeanDefinition在Spring容器中是用HashMap来维护的。我们同样的从入口着手,看其实如何实现载入的。

上一节我们谈到了WebApplicationContext的构建,在其构建完毕后,便调用了AbstractApplicationContext的refresh方法,其实这也是BeanDefinition载入的入口。从图中可以看到AbstractApplicationContext是XmlWebApplicationContext的基类。





refresh是很重要的一个方法,描述了整个初始化的过程,其中有一段代码通知子类去refresh BeanFactory,那么我们来看看AbstractRefreshableApplicationContext的核心代码:

protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//构建一个DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
//启动beanDefinition的载入
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}

代码中构建了一个DefaultListableBeanFactory,并且启动了beanDefinition的载入,具体的载入实现是在XmlWebApplicationContext中实现的。

2、BeanDefinition载入的过程

我们从上面的源代码就可以看到,在XmlWebApplicationContext中,通过方法loadBeanDefinition启动了载入,实际上载入的过程是在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 {
//获取xml文件和io的InputSource
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
//启动BeanDefiniton的载入
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
finally {
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();
}
}
}

我们再来看调用的doLoadBeanDefinitions方法:

protected [b]int doLoadBeanDefinitions(InputSource inputSource, Resource resource)[/b]
throws BeanDefinitionStoreException {
try {
int validationMode = getValidationModeForResource(resource);
//获取xml文件的Document对象,完成载入BeanDefinition。
Document doc = this.documentLoader.loadDocument(
inputSource, getEntityResolver(), this.errorHandler, validationMode, isNamespaceAware());
//BeanDefinition的解析(后面继续讨论)
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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐