zoukankan      html  css  js  c++  java
  • spring源码解析(资源加载)

    spring的配置文件

     获取spring容器的对象

    打开debug模式追踪spring的源码

     

     

     

     

     DefaultListableBeanFactory就是spring的容器用来管理bean对象

     

     

     DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,在AbstractBeanDefinitionReader中也保存了registry属性

     这两种方式,最后都会到

     

     public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
            Assert.notNull(encodedResource, "EncodedResource must not be null");
            if (this.logger.isInfoEnabled()) {
                this.logger.info("Loading XML bean definitions from " + encodedResource.getResource());
            }
    
            Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
            if (currentResources == null) {
                currentResources = new HashSet(4);
                this.resourcesCurrentlyBeingLoaded.set(currentResources);
            }
    
            if (!((Set)currentResources).add(encodedResource)) {
                throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
            } else {
                int var5;
                try {
                    InputStream inputStream = encodedResource.getResource().getInputStream();
    
                    try {
                        InputSource inputSource = new InputSource(inputStream);
                        if (encodedResource.getEncoding() != null) {
                            inputSource.setEncoding(encodedResource.getEncoding());
                        }
    
                        var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());//核心步骤
                    } finally {
                        inputStream.close();
                    }
                } catch (IOException var15) {
                    throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var15);
                } finally {
                    ((Set)currentResources).remove(encodedResource);
                    if (((Set)currentResources).isEmpty()) {
                        this.resourcesCurrentlyBeingLoaded.remove();
                    }
    
                }
    
                return var5;
            }
        }
    protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
            try {
                Document doc
    = this.doLoadDocument(inputSource, resource); return this.registerBeanDefinitions(doc, resource); } catch (BeanDefinitionStoreException var4) { throw var4; } catch (SAXParseException var5) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var5.getLineNumber() + " in XML document from " + resource + " is invalid", var5); } catch (SAXException var6) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var6); } catch (ParserConfigurationException var7) { throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var7); } catch (IOException var8) { throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var8); } catch (Throwable var9) { throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var9); } }
     public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
            BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
            int countBefore = this.getRegistry().getBeanDefinitionCount();
            documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
            return this.getRegistry().getBeanDefinitionCount() - countBefore;
        }

    创建一个DefaultBeanDefinitionDocumentReader对象来解析Document

     public XmlReaderContext createReaderContext(Resource resource) {
            return new XmlReaderContext(resource, this.problemReporter, this.eventListener, this.sourceExtractor, this, this.getNamespaceHandlerResolver());
        }

    XmlReaderContext对象有一个Reader属性,把XMLbeanDefinition给传进去

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

    从根节点开始解析

     protected void doRegisterBeanDefinitions(Element root) {
            BeanDefinitionParserDelegate parent = this.delegate;
            this.delegate = this.createDelegate(this.getReaderContext(), root, parent);
            if (this.delegate.isDefaultNamespace(root)) {
                String profileSpec = root.getAttribute("profile");
                if (StringUtils.hasText(profileSpec)) {
                    String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; ");
                    if (!this.getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
                        return;
                    }
                }
            }
    
            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);
                        } else {
                            delegate.parseCustomElement(ele);
                        }
                    }
                }
            } else {
                delegate.parseCustomElement(root);
            }
     private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
            if (delegate.nodeNameEquals(ele, "import")) {
                this.importBeanDefinitionResource(ele);
            } else if (delegate.nodeNameEquals(ele, "alias")) {
                this.processAliasRegistration(ele);
            } else if (delegate.nodeNameEquals(ele, "bean")) {
                this.processBeanDefinition(ele, delegate);
            } else if (delegate.nodeNameEquals(ele, "beans")) {
                this.doRegisterBeanDefinitions(ele);
            }
    
        }

    解析bean标签

    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
            BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
            if (bdHolder != null) {
                bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
    
                try {
                    BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
                } catch (BeanDefinitionStoreException var5) {
                    this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
                }
    
                this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
            }
    
        }
    public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
            String id = ele.getAttribute("id");
            String nameAttr = ele.getAttribute("name");
            List<String> aliases = new ArrayList();
            if (StringUtils.hasLength(nameAttr)) {
                String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
                aliases.addAll(Arrays.asList(nameArr));
            }
    
            String beanName = id;
            if (!StringUtils.hasText(id) && !aliases.isEmpty()) {
                beanName = (String)aliases.remove(0);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases");
                }
            }
    
            if (containingBean == null) {
                this.checkNameUniqueness(beanName, aliases, ele);
            }
    
            AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName, containingBean);
            if (beanDefinition != null) {
                if (!StringUtils.hasText(beanName)) {
                    try {
                        if (containingBean != null) {
                            beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);
                        } else {
                            beanName = this.readerContext.generateBeanName(beanDefinition);
                            String beanClassName = beanDefinition.getBeanClassName();
                            if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
                                aliases.add(beanClassName);
                            }
                        }
    
                        if (this.logger.isDebugEnabled()) {
                            this.logger.debug("Neither XML 'id' nor 'name' specified - using generated bean name [" + beanName + "]");
                        }
                    } catch (Exception var9) {
                        this.error(var9.getMessage(), ele);
                        return null;
                    }
                }
    
                String[] aliasesArray = StringUtils.toStringArray(aliases);
                return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
            } else {
                return null;
            }
        }

    解析bean标签内的所有信息,通过GenericBeanDefinition来存储这些信息

    public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
            String beanName = definitionHolder.getBeanName();
            registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
            String[] aliases = definitionHolder.getAliases();
            if (aliases != null) {
                String[] var4 = aliases;
                int var5 = aliases.length;
    
                for(int var6 = 0; var6 < var5; ++var6) {
                    String alias = var4[var6];
                    registry.registerAlias(beanName, alias);
                }
            }
    
        }

    把beandefinition对象注册到BeanDefinitionRegistry(也就是 DefaultListableBeanFactory中)

    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
            Assert.hasText(beanName, "Bean name must not be empty");
            Assert.notNull(beanDefinition, "BeanDefinition must not be null");
            if (beanDefinition instanceof AbstractBeanDefinition) {
                try {
                    ((AbstractBeanDefinition)beanDefinition).validate();
                } catch (BeanDefinitionValidationException var9) {
                    throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9);
                }
            }
    
            BeanDefinition oldBeanDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
            if (oldBeanDefinition != null) {
                if (!this.isAllowBeanDefinitionOverriding()) {
                    throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound.");
                }
    
                if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
                    if (this.logger.isWarnEnabled()) {
                        this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
                    }
                } else if (!beanDefinition.equals(oldBeanDefinition)) {
                    if (this.logger.isInfoEnabled()) {
                        this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
                    }
                } else if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
                }
    
                this.beanDefinitionMap.put(beanName, beanDefinition);
            } else {
                if (this.hasBeanCreationStarted()) {
                    Map var4 = this.beanDefinitionMap;
                    synchronized(this.beanDefinitionMap) {
                        this.beanDefinitionMap.put(beanName, beanDefinition);
                        List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
                        updatedDefinitions.addAll(this.beanDefinitionNames);
                        updatedDefinitions.add(beanName);
                        this.beanDefinitionNames = updatedDefinitions;
                        if (this.manualSingletonNames.contains(beanName)) {
                            Set<String> updatedSingletons = new LinkedHashSet(this.manualSingletonNames);
                            updatedSingletons.remove(beanName);
                            this.manualSingletonNames = updatedSingletons;
                        }
                    }
                } else {
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    this.beanDefinitionNames.add(beanName);
                    this.manualSingletonNames.remove(beanName);
                }
    
                this.frozenBeanDefinitionNames = null;
            }
    
            if (oldBeanDefinition != null || this.containsSingleton(beanName)) {
                this.resetBeanDefinition(beanName);
            }

    DefaultListableBeanFactory里的beanDefinitionMap会把bean标签的id作为key,beanDefinition作为value存储起来。至此,spring的配置文件加载就完成了.

    DefaultListableBeanFactory被保存在AbstractRefreshableConfigApplicationContext里

  • 相关阅读:
    [LintCode] Read Characters From File
    [LintCode] Insert Node in a Binary Search Tree
    [LintCode] Validate Binary Search Tree
    [LintCode] Merge Intervals
    [LintCode] Valid Parentheses
    [LintCode] First Position Unique Character
    三十七.MySQL视图 MySQL存储过程
    三十六.MHA集群概述 、 部署MHA集群 测试配置
    三十五.MySQL读写分离 MySQL多实例 、MySQL性能调优
    三十四.MySQL主从同步 、主从同步模式
  • 原文地址:https://www.cnblogs.com/lzh66/p/13115780.html
Copyright © 2011-2022 走看看