Spring IOC 源码分析-xml配置文件加载-注册

概述


spring中 对于xml配置文件的读取是依靠于Resource接口来完成的,Resource接口就是spring对于底层资源的抽象和封装,对于不同的资源比如文件系统,classpath路径,URL路径,spring提供了对应的Resource实现

这里写图片描述

xml配置文件加载第一步就是把 路径字符串封装成对应的Resource

这里spring用了实现了ResourceLoader的DefaultResourceLoader来解析配置文件并且转换成Resource

我们看下一下对应的方法

//location就是我们要加载的配置文件路径字符串

public Resource getResource(String location) {
  Assert.notNull(location, "Location must not be null");
   //这里可以定制不同的协议解析器,默认为空
for (ProtocolResolver protocolResolver : this.protocolResolvers) {
     Resource resource = protocolResolver.resolve(location, this);
if (resource != null) {
return resource;
     }
  }

if (location.startsWith("/")) {
return getResourceByPath(location);

  }

   //如果是classpath开头的资源,就使用对应的ClasspathResource来进行封装
else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());

  }
else {
try {

// Try to parse the location as a URL… 
//如果都不满足,就尝试用URL资源进行解析
 URL url = new URL(location);
return new UrlResource(url);
     }
catch (MalformedURLException ex) {

// No URL -> resolve as resource path 
   //解析失败后,最后用相对路径的方式进行解析.
 return getResourceByPath(location);
     }
  }
}

接着,spring默认用XmlBeanDefinitionReader 来处理后续的解析

public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {

return loadBeanDefinitions(new EncodedResource(resource));

}

这里使用一个编码包装器来对输入流进行解码处理

获取document

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)

throws BeanDefinitionStoreException {

try {

     Document doc = doLoadDocument(inputSource, resource);

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);

  }

}

进入doLoadDocument方法,这里我们看到 解析document的任务委托给了DefaultDocumentLoader类,充分显示了spring中职责分离的思想,一句话,就是专业的组件做专业的事情,不是分内的事情,就交给专业的组件处理

protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {

return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,

        getValidationModeForResource(resource), isNamespaceAware());

}

loadDocument方法本身没什么事情,主要是通过SAX解析xml文档,用的是java原始API,但是入口的地方有两个方法值得注意,一个是getEntityResolver,一个是getValidationModeForResource,获取的EntityResolver作用就是根据配置的文件的不同,选择不同的解析器,如果是DTD模式就使用dtd处理器,xsd模式使用xsd处理

最后一步就是把解析后的BeanDefinition注册

Spring IOC 源码分析-bean标签解析

Spring IOC源码分析-自定义标签加载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值