java加载xml配置文件_spring加载xml配置文件的源码分析

1 将资源文件封装成Resource

如Resource re = new ClassPathResource(“”);

将加载好的资源文件 通过XmlBeanFactory初始化

public class XmlBeanFactory extends DefaultListableBeanFactory {

private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);

public XmlBeanFactory(Resource resource) throws BeansException {

this(resource, null);

}

/**  该方法为资源加载的真正实现*/

public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {

super(parentBeanFactory);

this.reader.loadBeanDefinitions(resource);

}

}

3.加载bean

@Override

public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {

return loadBeanDefinitions(new EncodedResource(resource));

}

首先使用EncodedResource对resource进行封装,当设置了编码属性,spring会使用相应的编码作为输入流的编码

private EncodedResource(Resource resource, String encoding, Charset charset) {

super();

Assert.notNull(resource, "Resource must not be null");

this.resource = resource;

this.encoding = encoding;

this.charset = charset;

}

public Reader getReader() throws IOException {

if (this.charset != null) {

return new InputStreamReader(this.resource.getInputStream(), this.charset);

}

else if (this.encoding != null) {

return new InputStreamReader(this.resource.getInputStream(), this.encoding);

}

else {

return new InputStreamReader(this.resource.getInputStream());

}

}

上述代码构建好了一个有编码的InputStreamReader

下面这个方法才是真正的数据准备阶段

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 currentResources = this.resourcesCurrentlyBeingLoaded.get();

if (currentResources == null) {

currentResources = new HashSet(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());

}

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

}

}

}

//通过属性记录已经加载的资源,放入Threadlocal变量中

private final ThreadLocal> resourcesCurrentlyBeingLoaded =new NamedThreadLocal>("XML bean definition resources currently being loaded");

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

}

}

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

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

getValidationModeForResource(resource), isNamespaceAware());

}

//获取验证模式(DTD XSD两种验证模式)

protected int getValidationModeForResource(Resource resource) {

int validationModeToUse = getValidationMode();

//如果手动指定了验证模式则使用指定的验证模式

if (validationModeToUse != VALIDATION_AUTO) {

return validationModeToUse;

}

//没有指定 则使用自动检测

int detectedMode = detectValidationMode(resource);

if (detectedMode != VALIDATION_AUTO) {

return detectedMode;

}

// Hmm, we didn't get a clear indication... Let's assume XSD,

// since apparently no DTD declaration has been found up until

// detection stopped (before finding the document's root tag).

return VALIDATION_XSD;

}

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {

BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();

int countBefore = getRegistry().getBeanDefinitionCount();

documentReader.registerBeanDefinitions(doc, createReaderContext(resource));

return getRegistry().getBeanDefinitionCount() - countBefore;

}

此段代码 主要做了三件事:

获取对xml文件的验证模式

加载xml文件,并得到对应的Document

根据返回的Document注册Bean的信息

来源:[]()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值