1.Spring中最核心的两个类

1)DefaultListableBeanFactory

  XmlBeanFactory继承自DefaultListableBeanFactory,DefaultListableBeanFactory是整个bean加载的核心部分,是Spring加载及注册bean的默认实现

2)XmlBeanDefinitionReader

2.示例代码

BeanFactory bf=new XmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));

XmlBeanFactory.classpublic class XmlBeanFactory extends DefaultListableBeanFactory {private final XmlBeanDefinitionReader reader;public XmlBeanFactory(Resource resource) throws BeansException {this(resource, (BeanFactory)null);}public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {super(parentBeanFactory);this.reader = new XmlBeanDefinitionReader(this);this.reader.loadBeanDefinitions(resource);}
}
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {    return this.loadBeanDefinitions(new EncodedResource(resource));}
public int loadBeanDefinitions(EncodedResource encodedResource){....    InputSource inputSource = new InputSource(inputStream);//通过SAX方式解析XML文件....  this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());

}
 
 

3.配置文件的封装

Resource implements InputStreamResource

4.AbstractAutowireCapableBeanFactory.ignoreDependencyInterface()

忽略给定接口的自动装配功能

5.加载Bean

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {try {int validationMode = this.getValidationModeForResource(resource);//获取xml文件的验证模式
            Document doc = this.documentLoader.loadDocument(inputSource, this.getEntityResolver(), this.errorHandler, validationMode, this.isNamespaceAware());//加载XML文件return this.registerBeanDefinitions(doc, resource);//返回注册bean的信息} catch (BeanDefinitionStoreException var5) {throw var5;} catch (SAXParseException var6) {throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var6.getLineNumber() + " in XML document from " + resource + " is invalid", var6);} catch (SAXException var7) {throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var7);} catch (ParserConfigurationException var8) {throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var8);} catch (IOException var9) {throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var9);} catch (Throwable var10) {throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var10);}}

1)获取xml文件的验证模式

getValidationModeForResource(resource);
protected int getValidationModeForResource(Resource resource) {    int validationModeToUse = this.getValidationMode();    if (validationModeToUse != 1) {        return validationModeToUse;    } else {      //如果没有设定模式则进行自动检测模式        int detectedMode = this.detectValidationMode(resource);        return detectedMode != 1 ? detectedMode : 3;    }}

protected int detectValidationMode(Resource resource) {if (resource.isOpen()) {throw new BeanDefinitionStoreException("Passed-in Resource [" + resource + "] contains an open stream: " + "cannot determine validation mode automatically. Either pass in a Resource " + "that is able to create fresh streams, or explicitly specify the validationMode " + "on your XmlBeanDefinitionReader instance.");} else {InputStream inputStream;try {inputStream = resource.getInputStream();} catch (IOException var5) {throw new BeanDefinitionStoreException("Unable to determine validation mode for [" + resource + "]: cannot open InputStream. " + "Did you attempt to load directly from a SAX InputSource without specifying the " + "validationMode on your XmlBeanDefinitionReader instance?", var5);}try {          //将自动检测模式委托给了XmlValidationModeDetector类           return this.validationModeDetector.detectValidationMode(inputStream);        } catch (IOException var4) {           throw new BeanDefinitionStoreException("Unable to determine validation mode for [" + resource + "]: an error occurred whilst reading from the InputStream.", var4);        }      }   }

2)加载XML文件,并得到对应的Document

委托给DocumentLoader类

EntityResolver的用法

EntityResolver的作用是项目本身就可以提供一个如何寻找DTD声明的方法,即由程序来实现寻找DTD声明的过程,比如我们将DTD文件放到项目中某处,在实现时直接将此文档读取并返回给SAX即可。这样就避免了通过网络来寻找相应的声明。

验证文件默认的加载方式是通过URL进行网络下载获取,这样会造成延迟,用户体验也不好,一般的做法都是将验证文件放在自己的工程里。

public interface EntityResolver {public abstract InputSource resolveEntity (String publicId,String systemId)throws SAXException, IOException;}

3)返回注册bean的信息

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {      //单一职责原则BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();documentReader.setEnvironment(this.getEnvironment());int countBefore = this.getRegistry().getBeanDefinitionCount();      //加载及注册beandocumentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));return this.getRegistry().getBeanDefinitionCount() - countBefore;}

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {this.readerContext = readerContext;this.logger.debug("Loading bean definitions");Element root = doc.getDocumentElement();this.doRegisterBeanDefinitions(root);}

解析并注册BeanDefinitionsprotected void doRegisterBeanDefinitions(Element root) {String profileSpec = root.getAttribute("profile");if (StringUtils.hasText(profileSpec)) {Assert.state(this.environment != null, "Environment must be set for evaluating profiles");String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; ");if (!this.environment.acceptsProfiles(specifiedProfiles)) {return;}}BeanDefinitionParserDelegate parent = this.delegate;this.delegate = this.createHelper(this.readerContext, root, parent);this.preProcessXml(root);//模板方法模式this.parseBeanDefinitions(root, this.delegate);this.postProcessXml(root);this.delegate = parent;}

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {if (delegate.isDefaultNamespace(root)) {NodeList nl = root.getChildNodes();for(int i = 0; i < nl.getLength(); ++i) {Node node = nl.item(i);if (node instanceof Element) {Element ele = (Element)node;if (delegate.isDefaultNamespace(ele)) {this.parseDefaultElement(ele, delegate);//处理默认Bean声明} else {delegate.parseCustomElement(ele);//处理自定义Bean声明}}}} else {delegate.parseCustomElement(root);}}

转载于:https://www.cnblogs.com/lvjygogo/p/8974506.html

Spring源码学习笔记1相关推荐

  1. Spring源码学习笔记:经典设计模式之代理模式

    1.博客内容均出自于咕泡学院架构师第三期 2.架构师系列内容:架构师学习笔记(持续更新) 0.代理模式(Proxy Pattern) 指为其他对象提供一种代理,以控制对这个对象的访问.代理对象在客户端 ...

  2. Spring源码学习笔记:经典设计模式之策略模式

    1.博客内容均出自于咕泡学院架构师第三期 2.架构师系列内容:架构师学习笔记(持续更新) 0.策略模式(Strategy pattern) 指定义了算法家族,分别封装起来,让它们之间可以互相替换,此模 ...

  3. Spring源码学习笔记:经典设计模式之观察者模式

    1.博客内容均出自于咕泡学院架构师第三期 2.架构师系列内容:架构师学习笔记(持续更新) 0.观察者模式(Observer Pattern) 观察者模式也叫发布订阅模式.定义了对象之间的一对多依赖,让 ...

  4. Spring源码学习笔记:经典设计模式之装饰者模式

    1.博客内容均出自于咕泡学院架构师第三期 2.架构师系列内容:架构师学习笔记(持续更新) 0.装饰者模式(Decorator Pattern) 指在不改变原有对象的基础之上,将功能附加到对象上,提供了 ...

  5. Spring源码学习笔记:起源发展和核心模块主要职能

    1.博客内容均出自于咕泡学院架构师第三期 2.架构师系列内容:架构师学习笔记(持续更新) 1.Spring 的前世今生 早在 2007 年,一个基于 Java语言的开源框架正式发布,取了一个非常有活力 ...

  6. Spring源码学习笔记:Spring设计模式对比和Spring的OOB,BOP,AOP,IOC,DI/DL

    1.博客内容均出自于咕泡学院架构师第三期 2.架构师系列内容:架构师学习笔记(持续更新) 1.GOF 23总设计模式归纳 分类 设计模式 创建型 工厂方法模式(Factory Method).抽象工厂 ...

  7. 源码解析:Spring源码解析笔记(五)接口设计总览

    本文由colodoo(纸伞)整理 QQ 425343603 Java学习交流群(717726984) Spring解析笔记 启动过程部分已经完成,对启动过程源码有兴趣的朋友可以作为参考文章. 源码解析 ...

  8. spring源码深度解析 第2版 pdf_吹爆!阿里爆款Spring源码高级笔记,原来看懂源码如此简单...

    Spring的影响力想必无需与大家多说,如果你用spring,那么读读源码有助于对你最重要的工具的理解,好的框架源码也可以帮助我们理解什么是好代码. 刚参加工作那会,没想过去读源码,更没想过去改框架的 ...

  9. 结合Spring源码学习单例设计模式

    之前我学习了 Spring Ioc,明白了 Spring IoC 容器是一个管理Bean的容器,在Spring的定义中,它要求所有的IoC容器都需要实现接口 BeanFactory ,它是一个顶级容器 ...

最新文章

  1. PHP跳转到另一个画面,并且带着该行内的一个数值作为参数传递给下一个页面.能给例子吗...
  2. 慢系统调用与信号中断
  3. 糗事百科的网络爬虫(v0.2)源码及解析 .
  4. Tomcat的下载安装以及在eclipse中的配置
  5. python 支持向量机 导出参数_SVM支持向量机推导,工具介绍及python实现
  6. 上传文件插件(plupload)
  7. FAT32和NTFS的区别
  8. python神奇功能_16个你毫不知道的Python神奇技能
  9. Ubuntu下Android NDK环境搭建笔记
  10. pause容器作用_Kubernetes pod里一个特殊的容器:pause-amd64
  11. WEB开发常用软件集合
  12. Windows部署Tomcat8启动服务
  13. 项目管理学习总结(20)——小团队管理与大团队管理
  14. 无线模块数据加密,反码校验,发送字符串ABCDEFGHIJKLMNOP LED频闪
  15. 【MySQL】MySQL的四种事务隔离级别
  16. 转:瓦片地图TiledMap
  17. Android ANR问题总结
  18. python利用二分法实现求一个数的算术平方根
  19. AI挑战人类情感!机器人写诗、出书、开专栏背后透露了什么?
  20. 用Python自动生成数据分析报告

热门文章

  1. 比亚迪秦wince玩游戏_【新闻】1.5T比亚迪秦Pro或要降价/多款亲民新车上市!
  2. Premiere Pro CC2019安装资料及安装教程
  3. JAVA怎么查找错误,如何调试错误“符号查找错误:未定义符号”
  4. 计算机硬件市场调查清单,微型计算机组装与维护实用教程王际川第8章节组装计算机.ppt...
  5. python beautifulsoup抓取网页内容_利用Python和Beautiful Soup抓取网页内容
  6. oracle date类型,向Oracle中插入date数据类型
  7. 目录config.php怎么修改域名,config.php · wlphp/基于宝塔面板api给站点新增删除域名接口 - Gitee.com...
  8. 计算机科普知识主题,科普知识3
  9. 账单比较java代码_Java代码比较两个文件的MD5
  10. iis Service Unavailable解决方法(权限问题)