Spring源码之XmlBeanDefinitionReader与Resource
一、DefaultListableBeanFactory类,
里面有一个成员变量beanDefinitionMap,Bean定义对象的Map, BeanDefinition就对应XML的属性配置
/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();
二、上一篇讲到加载,读取xml的步骤。
1、ClassPathResource resource = new ClassPathSource("beans.xml");
2、DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); //创建DefaultListableBeanFactory对象
3、XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory); //创建XmlBeanDefinitionReader 对象
4、reader.loadBeanDefinitions(resource); //加载bean的定义,bean来自资源文件。
如何定位资源,解析资源?
下面进行具体分析:
1、ClassPathResource resource = new ClassPathSource("beans.xml");
首先进入ClassPathResource,进入构造函数
进入第二个构造函数
Assert翻译为中文为“断言”, 就是断定某一个实际的值就是自己预期想要得到的,如果不一样就抛出异常。
Assert.notNull(path, "Path must not be null");
如果path为空,就抛出异常
4、reader.loadBeanDefinitions(resource);
进入loadBeanDefinitions方法
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(new EncodedResource(resource));
}
然后进入
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(new EncodedResource(resource));
} /**
* Load bean definitions from the specified XML file.
* @param encodedResource the resource descriptor for the XML file,
* allowing to specify an encoding to use for parsing the file
* @return the number of bean definitions found
* @throws BeanDefinitionStoreException in case of loading or parsing errors
*/
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());
}
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(inputSource, encodedResource.getResource()); 方法。
loadDocument用来加载生成Document对象,代表xml文档对应的Document对象。
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) {
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);
}
}
loadDocument的方法如下:
public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception { DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);
if (logger.isDebugEnabled()) {
logger.debug("Using JAXP provider [" + factory.getClass().getName() + "]");
}
DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);
return builder.parse(inputSource);
}
registerBeanDefinitions方法
/**
* Register the bean definitions contained in the given DOM document.
* Called by <code>loadBeanDefinitions</code>.
* <p>Creates a new instance of the parser class and invokes
* <code>registerBeanDefinitions</code> on it.
* @param doc the DOM document
* @param resource the resource descriptor (for context information)
* @return the number of bean definitions found
* @throws BeanDefinitionStoreException in case of parsing errors
* @see #loadBeanDefinitions
* @see #setDocumentReaderClass
* @see BeanDefinitionDocumentReader#registerBeanDefinitions
*/
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
documentReader.setEnvironment(this.getEnvironment());
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
查看BeanDefinitionDocumentReader,
里面有一个BeanDefinitionParserDelegate,真正实现xml解析就是这个类,类中定义了常量对应的xml属性
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
doRegisterBeanDefinitions(root);
Spring源码之XmlBeanDefinitionReader与Resource的更多相关文章
- Spring源码入门——XmlBeanDefinitionReader解析
接上篇[] ,我们看到BeanDefinitionReader解决的是从资源文件(xml,propert)到BeanDefinition集合的过程.所以BeanDefinitionReader接口有两 ...
- 【Spring 源码】Spring 加载资源并装配对象的过程(XmlBeanDefinitionReader)
Spring 加载资源并装配对象过程 在Spring中对XML配置文件的解析从3.1版本开始不再推荐使用XmlBeanFactory而是使用XmlBeanDefinitionReader. Class ...
- Spring源码分析——资源访问利器Resource之实现类分析
今天来分析Spring的资源接口Resource的各个实现类.关于它的接口和抽象类,参见上一篇博文——Spring源码分析——资源访问利器Resource之接口和抽象类分析 一.文件系统资源 File ...
- Spring源码分析——资源访问利器Resource之接口和抽象类分析
从今天开始,一步步走上源码分析的路.刚开始肯定要从简单着手.我们先从Java发展史上最强大的框架——Spring...旗下的资源抽象接口Resource开始吧. 我看了好多分析Spring源码的,每每 ...
- spring源码分析(一)IoC、DI
创建日期:2016.08.06 修改日期:2016.08.07 - 2016.08.12 交流QQ:992591601 参考书籍:<spring源码深度解析>.<spring技术内幕 ...
- 初始化IoC容器(Spring源码阅读)
初始化IoC容器(Spring源码阅读) 我们到底能走多远系列(31) 扯淡: 有个问题一直想问:各位你们的工资剩下来会怎么处理?已婚的,我知道工资永远都是不够的.未婚的你们,你们是怎么分配工资的? ...
- spring源码浅析——IOC
=========================================== 原文链接: spring源码浅析--IOC 转载请注明出处! ======================= ...
- Spring源码情操陶冶-AbstractApplicationContext#obtainFreshBeanFactory
前言-阅读源码有利于陶冶情操,本文承接前文Spring源码情操陶冶-AbstractApplicationContext 约束: 本文指定contextClass为默认的XmlWebApplicati ...
- 【Spring源码分析】配置文件读取流程
前言 Spring配置文件读取流程本来是和http://www.cnblogs.com/xrq730/p/6285358.html一文放在一起的,这两天在看Spring自定义标签的时候,感觉对Spri ...
随机推荐
- centos7误删除python2.7导致的python和yum不可用处理
centos7误删除python2.7后导致yum不可用: 问题截图 解决方法: 1.在opt目录下创建site_package/python3递归目录,然后下载以下RPM包,并存入/opt/site ...
- pyserial 挺强大的
Ref: https://pythonhosted.org/pyserial/ pyserial写的很规范,无论安装和使用都非常的容易,目前使用下来非常好. 没有使用它做过压力测试,不知道表现如何. ...
- mock工具:mock.js 和vscode faker,moco
参考:https://www.jianshu.com/p/8453b045544f mock.js主要用于模仿接口返回,可与原生ajax一起使用. 参考:https://www.jianshu.com ...
- 解决Antimalware Service Executable CPU占用高的问题
windows8/8.1,WIN10自带的安全软件Windows defender还不错,基本可以不用装其他杀毒软件了. 但是其进程Antimalware Service Executable 出现C ...
- Excel技巧大全
1.一列数据同时除以10000 复制10000所在单元格,选取数据区域 - 选择粘性粘贴 - 除 2.同时冻结第1行和第1列 选取第一列和第一行交汇处的墙角位置B2,窗口 - 冻结窗格 3.快速把公式 ...
- go http编程
http的请求包包含 请求行,请求头,空行,请求体go的http编程 http server.go package main import "net/http" func main ...
- Django --- ORM表查询
目录 使用数据库之前的配置工作 单表操作常用的方法 一对多字段的增删改查 多对多字段数据的增删改查 跨表查询 聚合函数 分组查询 F与Q查询 使用数据库之前的配置工作 settings.py中的配置 ...
- Vector(同步)和Arraylist(异步)的异同
// 同步 异步 //1 同步 //2 异步 //未响应 = 假死 占用内存过多 内存无法进行处理 //请求方式:同步 异步 //网页的展现过程中:1 css文件的下载 ...
- CSP-J总结&题解
总结: 这一次,最后一次,还是不行啊. 文件操作方面:没有FCLOSE,血的教训. 考场复盘: 首先一二题没什么好讲的,秒切.但是第三题由于一开始看出来是完全背包,但是好像又不是,去年又有摆渡车阴影, ...
- learning java ATW ScrollPane
import java.awt.*; public class ScrollPaneTest { public static void main(String[] args) { var f = ne ...