1.Spring中最核心的两个类

1)DefaultListableBeanFactory

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

2)XmlBeanDefinitionReader

2.示例代码

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

  1. XmlBeanFactory.class
    public class XmlBeanFactory extends DefaultListableBeanFactory {
  2. private final XmlBeanDefinitionReader reader;
  3.  
  4. public XmlBeanFactory(Resource resource) throws BeansException {
  5. this(resource, (BeanFactory)null);
  6. }
  7.  
  8. public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
  9. super(parentBeanFactory);
  10. this.reader = new XmlBeanDefinitionReader(this);
  11. this.reader.loadBeanDefinitions(resource);
  12. }
  13. }
  1. public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
    return this.loadBeanDefinitions(new EncodedResource(resource));
    }
  1. public int loadBeanDefinitions(EncodedResource encodedResource){
    ....  

      InputSource inputSource = new InputSource(inputStream);//通过SAX方式解析XML文件
    ....
      this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
  2.  
  3. }
  1.  
  1.  

3.配置文件的封装

  1. Resource implements InputStreamResource

4.AbstractAutowireCapableBeanFactory.ignoreDependencyInterface()

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

5.加载Bean

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

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

  1. getValidationModeForResource(resource);
  1. 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;
    }
    }
  1. protected int detectValidationMode(Resource resource) {
  2. if (resource.isOpen()) {
  3. 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.");
  4. } else {
  5. InputStream inputStream;
  6. try {
  7. inputStream = resource.getInputStream();
  8. } catch (IOException var5) {
  9. 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);
  10. }
  11.  
  12. 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进行网络下载获取,这样会造成延迟,用户体验也不好,一般的做法都是将验证文件放在自己的工程里。

  1. public interface EntityResolver {
  2. public abstract InputSource resolveEntity (String publicId,
  3. String systemId)
  4. throws SAXException, IOException;
  5.  
  6. }

3)返回注册bean的信息

  1. public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
          //单一职责原则
  2. BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
  3. documentReader.setEnvironment(this.getEnvironment());
  4. int countBefore = this.getRegistry().getBeanDefinitionCount();
          //加载及注册bean
  5. documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
  6. return this.getRegistry().getBeanDefinitionCount() - countBefore;
  7. }
  1. public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
  2. this.readerContext = readerContext;
  3. this.logger.debug("Loading bean definitions");
  4. Element root = doc.getDocumentElement();
  5. this.doRegisterBeanDefinitions(root);
  6. }
  1. 解析并注册BeanDefinitions
    protected void doRegisterBeanDefinitions(Element root) {
  2. String profileSpec = root.getAttribute("profile");
  3. if (StringUtils.hasText(profileSpec)) {
  4. Assert.state(this.environment != null, "Environment must be set for evaluating profiles");
  5. String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; ");
  6. if (!this.environment.acceptsProfiles(specifiedProfiles)) {
  7. return;
  8. }
  9. }
  10.  
  11. BeanDefinitionParserDelegate parent = this.delegate;
  12. this.delegate = this.createHelper(this.readerContext, root, parent);
  13. this.preProcessXml(root);//模板方法模式
  14. this.parseBeanDefinitions(root, this.delegate);
  15. this.postProcessXml(root);
  16. this.delegate = parent;
  17. }
  1. protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
  2. if (delegate.isDefaultNamespace(root)) {
  3. NodeList nl = root.getChildNodes();
  4.  
  5. for(int i = 0; i < nl.getLength(); ++i) {
  6. Node node = nl.item(i);
  7. if (node instanceof Element) {
  8. Element ele = (Element)node;
  9. if (delegate.isDefaultNamespace(ele)) {
  10. this.parseDefaultElement(ele, delegate);//处理默认Bean声明
  11. } else {
  12. delegate.parseCustomElement(ele);//处理自定义Bean声明
  13. }
  14. }
  15. }
  16. } else {
  17. delegate.parseCustomElement(root);
  18. }
  19. }

Spring源码学习笔记1的更多相关文章

  1. Spring源码学习笔记9——构造器注入及其循环依赖

    Spring源码学习笔记9--构造器注入及其循环依赖 一丶前言 前面我们分析了spring基于字段的和基于set方法注入的原理,但是没有分析第二常用的注入方式(构造器注入)(第一常用字段注入),并且在 ...

  2. Spring 源码学习笔记10——Spring AOP

    Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...

  3. Spring 源码学习笔记11——Spring事务

    Spring 源码学习笔记11--Spring事务 Spring事务是基于Spring Aop的扩展 AOP的知识参见<Spring 源码学习笔记10--Spring AOP> 图片参考了 ...

  4. Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点

    Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...

  5. spring源码学习笔记之容器的基本实现(一)

    前言 最近学习了<<Spring源码深度解析>>受益匪浅,本博客是对学习内容的一个总结.分享,方便日后自己复习或与一同学习的小伙伴一起探讨之用. 建议与源码配合使用,效果更嘉, ...

  6. Spring源码学习笔记之bean标签属性介绍及作用

    传统的Spring项目, xml 配置bean在代码中是经常遇到, 那么在配置bean的时候,这些属性的作用是什么呢? 虽然说现在boot项目兴起,基于xml配置的少了很多, 但是如果能够了解这些标签 ...

  7. Spring源码学习笔记之基于ClassPathXmlApplicationContext进行bean标签解析

    bean 标签在spring的配置文件中, 是非常重要的一个标签, 即便现在boot项目比较流行, 但是还是有必要理解bean标签的解析流程,有助于我们进行 基于注解配置, 也知道各个标签的作用,以及 ...

  8. Spring源码学习笔记2

    1.默认标签的解析 对四种不同标签的解析 private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate dele ...

  9. spring源码学习之路---IOC初探(二)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章当中我没有提及具体的搭 ...

随机推荐

  1. idea 本地tomcat启动控制台乱码问题

    问题:本地tomcat启动,控制台出现中文乱码: 解决办法: 安装了idea发现启动tomcat的时候控制台会有乱码问题,在tomcat配置中添加在VM options填写-Dfile.encodin ...

  2. (JavaScript)实现上传图片实时预览和(文件)大小判断

    唉,为什么我一个做大数据和后端的要为前端耗尽心力啊??!! 昨天在做一个网页时遇到了一个问题,有一处需要插入图片,我原本的想法是获取到上传文件的URL,然后动态插入img标签,设置src为图片的URL ...

  3. 德邦总管 修改oracle数据库用户密码的方法

    WIN+R打开运行窗口,输入cmd进入命令行: 输入sqlplus ,输入用户名,输入口令(如果是超级管理员SYS的话需在口令之后加上as sysdba)进入sql命令行:    连接成功后,输入“s ...

  4. 移动App测试中的最佳做法

    一说起软件测试,测试员想到肯定是去检查文件,功能,API,性能并确定软件是否安全,以及关于软件特定部分的其他事项.但是对于移动测试,测试员不得不基于用户移动使用模式考虑移动相关的功能. 本文是基于我的 ...

  5. 从零开始 —— Canvas(一)

    从零开始-Canvas 1.颜色.样式和阴影 属性 a.fillStyle(设置或返回用于填充绘画的颜色.渐变或模式) 语法:context.fillStyle = color(颜色值) | grad ...

  6. this应用详解-js原生

    学习记录,以防遗忘,适合新手解惑.老鸟避让! 在微信H5的开发中,很多页面都是简单的一个模型item在加上很多很多数据组成起来的.例如微信朋友圈,仔细观察,他的一个基本模型就是 “头像图片 + 用户昵 ...

  7. inotify事件监控工具

    inotify事件监控工具   rsync + inotify 组合的起源   inotify优缺点 优点:监控文件系统事件变化,通过同步工具实现实时数据同步 缺点:并发如果大于200个文件(10-1 ...

  8. jQuery对象与DOM对象互相转换

    1.jQuey对象转DOM对象 a. [index]   代码如下: var $a = $("#a"); //jQuery对象 var a = $a[]; //DOM对象 b. g ...

  9. Android : Camera之camx hal架构

    一.camx的代码结构 目前主流的机型都使用camx架构,这个架构和之前架构的主要区别就是 芯片接口层的代码从hardware/qcom 迁移到 vendor/qcom/proprietary/下面, ...

  10. ssh整合报错严重: Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxx'

    错误描述:eclipse整合ssh的时候 报不能创建名字为xxx的对象 信息: Destroying singletons in org.springframework.beans.factory.s ...