zoukankan      html  css  js  c++  java
  • 默认标签的解析过程(三)parseDefaultElement

        private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
            if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
                importBeanDefinitionResource(ele);
            }
            else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
                processAliasRegistration(ele);
            }
            else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
                processBeanDefinition(ele, delegate);
            }
            else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
                // recurse
                doRegisterBeanDefinitions(ele);
            }
        }

    可以看出主要对(import,  alias, bean, beans进行解析)

    IMPORT_ELEMENT
    ALIAS_ELEMENT
    BEAN_ELEMENT
    NESTED_BEANS_ELEMENT
    在上一篇文章DefaultListableBeanFactory只是保存一些bean解析出后的信息的注册基本信息到
    beanDefinitionMap 
    /** Resolver to use for checking if a bean definition is an autowire candidate */
    	private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
    
    	/** Map from dependency type to corresponding autowired value */
    	private final Map<Class<?>, Object> resolvableDependencies = new HashMap<Class<?>, Object>(16);
    
    	/** Map of bean definition objects, keyed by bean。 name BeanDefinition主要是保存Bean 的名字,class 依赖等待信息*/ 
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
    /** Map of singleton bean names keyed by bean class */
    private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
    /** Map of non-singleton bean names keyed by bean class */
    private final Map<Class<?>, String[]> nonSingletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
    /** List of bean definition names, in registration order */
    private final List<String> beanDefinitionNames = new ArrayList<String>();

     Bean解析:

        /**
         * Process the given bean element, parsing the bean definition
         * and registering it with the registry.
         */
        protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
            BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);//根据ele解析出所包含的所有信息
            if (bdHolder != null) {
                bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
                try {
                    // Register the final decorated instance.注册bdHold到beanDefinationMap
                    BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
                }
                catch (BeanDefinitionStoreException ex) {
                    getReaderContext().error("Failed to register bean definition with name '" +
                            bdHolder.getBeanName() + "'", ele, ex);
                }
                // Send registration event.
                getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
            }
        }
    /**
         * Parses the supplied <code>&lt;bean&gt;</code> element. May return <code>null</code>
         * if there were errors during parse. Errors are reported to the
         * {@link org.springframework.beans.factory.parsing.ProblemReporter}.
         */
        public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
            return parseBeanDefinitionElement(ele, null);
        }
    
        /**
         * Parses the supplied <code>&lt;bean&gt;</code> element. May return <code>null</code>
         * if there were errors during parse. Errors are reported to the
         * {@link org.springframework.beans.factory.parsing.ProblemReporter}.
         */
        public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
            String id = ele.getAttribute(ID_ATTRIBUTE);
            String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
    
            List<String> aliases = new ArrayList<String>();
            if (StringUtils.hasLength(nameAttr)) {
                String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
                aliases.addAll(Arrays.asList(nameArr));
            }
    
            String beanName = id;
            if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
                beanName = aliases.remove(0);
                if (logger.isDebugEnabled()) {
                    logger.debug("No XML 'id' specified - using '" + beanName +
                            "' as bean name and " + aliases + " as aliases");
                }
            }
    
            if (containingBean == null) {
                checkNameUniqueness(beanName, aliases, ele);
            }
    
            AbstractBeanDefinition beanDefinition = 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);
                            // Register an alias for the plain bean class name, if still possible,
                            // if the generator returned the class name plus a suffix.
                            // This is expected for Spring 1.2/2.0 backwards compatibility.
                            String beanClassName = beanDefinition.getBeanClassName();
                            if (beanClassName != null &&
                                    beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
                                    !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
                                aliases.add(beanClassName);
                            }
                        }
                        if (logger.isDebugEnabled()) {
                            logger.debug("Neither XML 'id' nor 'name' specified - " +
                                    "using generated bean name [" + beanName + "]");
                        }
                    }
                    catch (Exception ex) {
                        error(ex.getMessage(), ele);
                        return null;
                    }
                }
                String[] aliasesArray = StringUtils.toStringArray(aliases);
                return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
            }
    
            return null;
        }


    /**
         * Parse the bean definition itself, without regard to name or aliases. May return
         * <code>null</code> if problems occurred during the parsing of the bean definition.
         */
        public AbstractBeanDefinition parseBeanDefinitionElement(
                Element ele, String beanName, BeanDefinition containingBean) {
    
            this.parseState.push(new BeanEntry(beanName));
    
            String className = null;
            if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
                className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
            }
    
            try {
                String parent = null;
                if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
                    parent = ele.getAttribute(PARENT_ATTRIBUTE);
                }
                AbstractBeanDefinition bd = createBeanDefinition(className, parent); //返回GenericBeanDefinition 用于承载beanDefi
    
                parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); //解析各种attr到bd
                bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
    
                parseMetaElements(ele, bd);//<bean><meta..到bd
                parseLookupOverrideSubElements(ele, bd.getMethodOverrides());  //<bean><lookup-method...到 bd
                parseReplacedMethodSubElements(ele, bd.getMethodOverrides());//<bean><replaced-method 到bd 动态替换bean里面的方法
    
                parseConstructorArgElements(ele, bd);//<bean><constructor-arg... 到bd
                parsePropertyElements(ele, bd);  //<bean><property....到bd
                parseQualifierElements(ele, bd); //<bean><qualifier 到bd
    
                bd.setResource(this.readerContext.getResource());
                bd.setSource(extractSource(ele));
    
                return bd;
            }
            catch (ClassNotFoundException ex) {
                error("Bean class [" + className + "] not found", ele, ex);
            }
            catch (NoClassDefFoundError err) {
                error("Class that bean class [" + className + "] depends on not found", ele, err);
            }
            catch (Throwable ex) {
                error("Unexpected failure during bean definition parsing", ele, ex);
            }
            finally {
                this.parseState.pop();
            }
    
            return null;
        }
    
    
    
     

     alians 也与bean类似

     

     
     
     
     
  • 相关阅读:
    ASP.NET Core管道详解[4]: 中间件委托链
    从执行上下文角度重新理解.NET(Core)的多线程编程[3]:安全上下文
    从执行上下文角度重新理解.NET(Core)的多线程编程[2]:同步上下文
    从执行上下文角度重新理解.NET(Core)的多线程编程[1]:基于调用链的”参数”传递
    ASP.NET Core管道详解[3]: Pipeline = IServer + IHttpApplication
    ASP.NET Core管道详解[2]: HttpContext本质论
    ASP.NET Core应用基本编程模式[5]:如何放置你的初始化代码
    如何实现Http请求报头的自动转发[设计篇]
    如何实现Http请求报头的自动转发[应用篇]
    采用”传统”方式获取当前HttpContext
  • 原文地址:https://www.cnblogs.com/daxiong225/p/9533714.html
Copyright © 2011-2022 走看看