zoukankan      html  css  js  c++  java
  • Spring源码学习笔记1

    1.Spring中最核心的两个类

    1)DefaultListableBeanFactory

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

    2)XmlBeanDefinitionReader

    2.示例代码

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

    XmlBeanFactory.class
    public
    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();
          //加载及注册bean documentReader.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);
        }
    解析并注册BeanDefinitions
    protected
    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);
            }
        }
  • 相关阅读:
    【题解】【字符串】【BFS】【Leetcode】Word Ladder
    Python CSV模块处理文件读写
    【题解】【排列组合】【回溯】【Leetcode】Generate Parentheses
    【题解】【链表】【Leetcode】Linked List Cycle II
    【题解】【排列组合】【回溯】【Leetcode】Gray Code
    【题解】【位操作】【Leetcode】Single Number II
    【题解】【数组】【查找】【Leetcode】Search Insert Position
    JAVAWEB的Listener
    Hibernate的检索方式--查询数据的方式
    Hibernate的批量处理和分页技术、投影技术
  • 原文地址:https://www.cnblogs.com/lvjygogo/p/8974506.html
Copyright © 2011-2022 走看看