美文网首页
Spring源码解析(五)-XmlBeanDefinitionR

Spring源码解析(五)-XmlBeanDefinitionR

作者: Jerry_dong | 来源:发表于2017-06-21 21:58 被阅读0次

    上一篇博客中我们讲到了registerBeanDefinitions方法,这一篇我们继续,先让我们看看源码是怎么实现的

    //根据给定的DOM文件注册Bean定义
    public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
            //得到BeanDefinitionDocumentReader来对xml格式的BeanDefinition解析
            BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
            //获得容器中已经注册的Bean数量
            int countBefore = getRegistry().getBeanDefinitionCount();
            //核心代码,接下来详细分析
            //createReaderContext方法用来创建一个XmlReaderContext实例
            documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
            //统计出本次注册bean的数量
            return getRegistry().getBeanDefinitionCount() - countBefore;
        }
    

    BeanDefinitionDocumentReader是一个接口,我们先来看看他的默认实现类DefaultBeanDefinitionDocumentReader

    DefaultBeanDefinitionDocumentReader

    1.成员变量

        public static final String BEAN_ELEMENT = BeanDefinitionParserDelegate.BEAN_ELEMENT;
    
        public static final String NESTED_BEANS_ELEMENT = "beans";
    
        public static final String ALIAS_ELEMENT = "alias";
    
        public static final String NAME_ATTRIBUTE = "name";
    
        public static final String ALIAS_ATTRIBUTE = "alias";
    
        public static final String IMPORT_ELEMENT = "import";
    
        public static final String RESOURCE_ATTRIBUTE = "resource";
    
        public static final String PROFILE_ATTRIBUTE = "profile";
    
    
        protected final Log logger = LogFactory.getLog(getClass());
    
        private XmlReaderContext readerContext;
    
        private BeanDefinitionParserDelegate delegate;
    

    **2.BeanDefinitionParserDelegate **

    public class BeanDefinitionParserDelegate {
    
        public static final String BEANS_NAMESPACE_URI = "http://www.springframework.org/schema/beans";
    
        public static final String MULTI_VALUE_ATTRIBUTE_DELIMITERS = ",; ";
    
        /**
         * Value of a T/F attribute that represents true.
         * Anything else represents false. Case seNsItive.
         */
        public static final String TRUE_VALUE = "true";
    
        public static final String FALSE_VALUE = "false";
    
        public static final String DEFAULT_VALUE = "default";
    
        public static final String DESCRIPTION_ELEMENT = "description";
    
        public static final String AUTOWIRE_NO_VALUE = "no";
    
        public static final String AUTOWIRE_BY_NAME_VALUE = "byName";
    
        public static final String AUTOWIRE_BY_TYPE_VALUE = "byType";
    
        public static final String AUTOWIRE_CONSTRUCTOR_VALUE = "constructor";
    
        public static final String AUTOWIRE_AUTODETECT_VALUE = "autodetect";
    
        public static final String DEPENDENCY_CHECK_ALL_ATTRIBUTE_VALUE = "all";
    
        public static final String DEPENDENCY_CHECK_SIMPLE_ATTRIBUTE_VALUE = "simple";
    
        public static final String DEPENDENCY_CHECK_OBJECTS_ATTRIBUTE_VALUE = "objects";
    
        public static final String NAME_ATTRIBUTE = "name";
    
        public static final String BEAN_ELEMENT = "bean";
    
        public static final String META_ELEMENT = "meta";
    
        public static final String ID_ATTRIBUTE = "id";
    
        public static final String PARENT_ATTRIBUTE = "parent";
    
        public static final String CLASS_ATTRIBUTE = "class";
    
        public static final String ABSTRACT_ATTRIBUTE = "abstract";
    
        public static final String SCOPE_ATTRIBUTE = "scope";
    
        private static final String SINGLETON_ATTRIBUTE = "singleton";
    
        public static final String LAZY_INIT_ATTRIBUTE = "lazy-init";
    
        public static final String AUTOWIRE_ATTRIBUTE = "autowire";
    
        public static final String AUTOWIRE_CANDIDATE_ATTRIBUTE = "autowire-candidate";
    
        public static final String PRIMARY_ATTRIBUTE = "primary";
    
        public static final String DEPENDENCY_CHECK_ATTRIBUTE = "dependency-check";
    
        public static final String DEPENDS_ON_ATTRIBUTE = "depends-on";
    
        public static final String INIT_METHOD_ATTRIBUTE = "init-method";
    
        public static final String DESTROY_METHOD_ATTRIBUTE = "destroy-method";
    
        public static final String FACTORY_METHOD_ATTRIBUTE = "factory-method";
    
        public static final String FACTORY_BEAN_ATTRIBUTE = "factory-bean";
    
        public static final String CONSTRUCTOR_ARG_ELEMENT = "constructor-arg";
    
        public static final String INDEX_ATTRIBUTE = "index";
    
        public static final String TYPE_ATTRIBUTE = "type";
    
        public static final String VALUE_TYPE_ATTRIBUTE = "value-type";
    
        public static final String KEY_TYPE_ATTRIBUTE = "key-type";
    
        public static final String PROPERTY_ELEMENT = "property";
    
        public static final String REF_ATTRIBUTE = "ref";
    
        public static final String VALUE_ATTRIBUTE = "value";
    
        public static final String LOOKUP_METHOD_ELEMENT = "lookup-method";
    
        public static final String REPLACED_METHOD_ELEMENT = "replaced-method";
    
        public static final String REPLACER_ATTRIBUTE = "replacer";
    
        public static final String ARG_TYPE_ELEMENT = "arg-type";
    
        public static final String ARG_TYPE_MATCH_ATTRIBUTE = "match";
    
        public static final String REF_ELEMENT = "ref";
    
        public static final String IDREF_ELEMENT = "idref";
    
        public static final String BEAN_REF_ATTRIBUTE = "bean";
    
        public static final String LOCAL_REF_ATTRIBUTE = "local";
    
        public static final String PARENT_REF_ATTRIBUTE = "parent";
    
        public static final String VALUE_ELEMENT = "value";
    
        public static final String NULL_ELEMENT = "null";
    
        public static final String ARRAY_ELEMENT = "array";
    
        public static final String LIST_ELEMENT = "list";
    
        public static final String SET_ELEMENT = "set";
    
        public static final String MAP_ELEMENT = "map";
    
        public static final String ENTRY_ELEMENT = "entry";
    
        public static final String KEY_ELEMENT = "key";
    
        public static final String KEY_ATTRIBUTE = "key";
    
        public static final String KEY_REF_ATTRIBUTE = "key-ref";
    
        public static final String VALUE_REF_ATTRIBUTE = "value-ref";
    
        public static final String PROPS_ELEMENT = "props";
    
        public static final String PROP_ELEMENT = "prop";
    
        public static final String MERGE_ATTRIBUTE = "merge";
    
        public static final String QUALIFIER_ELEMENT = "qualifier";
    
        public static final String QUALIFIER_ATTRIBUTE_ELEMENT = "attribute";
    
        public static final String DEFAULT_LAZY_INIT_ATTRIBUTE = "default-lazy-init";
    
        public static final String DEFAULT_MERGE_ATTRIBUTE = "default-merge";
    
        public static final String DEFAULT_AUTOWIRE_ATTRIBUTE = "default-autowire";
    
        public static final String DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE = "default-dependency-check";
    
        public static final String DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE = "default-autowire-candidates";
    
        public static final String DEFAULT_INIT_METHOD_ATTRIBUTE = "default-init-method";
    
        public static final String DEFAULT_DESTROY_METHOD_ATTRIBUTE = "default-destroy-method";
    
    
        protected final Log logger = LogFactory.getLog(getClass());
    
        private final XmlReaderContext readerContext;
    
        private final DocumentDefaultsDefinition defaults = new DocumentDefaultsDefinition();
    
        private final ParseState parseState = new ParseState();
    
        /**
         * Stores all used bean names so we can enforce uniqueness on a per
         * beans-element basis. Duplicate bean ids/names may not exist within the
         * same level of beans element nesting, but may be duplicated across levels.
         */
        private final Set<String> usedNames = new HashSet<String>();
        ...
        }
    

    3.registerBeanDefinitions方法

        @Override
        public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
            //获得XML描述符(拥有XmlBeanDefinitionReader,NamespaceHandlerResolver)2个成员变量
            this.readerContext = readerContext;
            logger.debug("Loading bean definitions");
            //获得Document的根元素  (<beans>)
            Element root = doc.getDocumentElement();
            doRegisterBeanDefinitions(root);
        }
    
        protected void doRegisterBeanDefinitions(Element root) {
            // Any nested <beans> elements will cause recursion in this method. In
            // order to propagate and preserve <beans> default-* attributes correctly,
            // keep track of the current (parent) delegate, which may be null. Create
            // the new (child) delegate with a reference to the parent for fallback purposes,
            // then ultimately reset this.delegate back to its original (parent) reference.
            // this behavior emulates a stack of delegates without actually necessitating one.
            //从上述的注释中可以看出里面有一个隐式的递归
            BeanDefinitionParserDelegate parent = this.delegate;
            //创建BeanDefinitionParserDelegate,用于完成真正的解析过程  
            this.delegate = createDelegate(getReaderContext(), root, parent);
            //对beans中的profile属性做处理,不是很重要,这里不做解释了
            if (this.delegate.isDefaultNamespace(root)) {
                String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
                if (StringUtils.hasText(profileSpec)) {
                    String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
                            profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
                    if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
                        return;
                    }
                }
            }
            //这里用到了模板模式
            //在解析Bean定义之前,进行自定义的解析,增强解析过程的可扩展性
            preProcessXml(root);
            //解析bean定义,下章详解
            parseBeanDefinitions(root, this.delegate);
            //在解析Bean定义之后,进行自定义的解析,增强解析过程的可扩展性
            postProcessXml(root);
    
            this.delegate = parent;
        }
    
        protected BeanDefinitionParserDelegate createDelegate(
                XmlReaderContext readerContext, Element root, BeanDefinitionParserDelegate parentDelegate) {
            //构造BeanDefinitionParserDelegate
            BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext);
            delegate.initDefaults(root, parentDelegate);
            return delegate;
        }
    
       public void initDefaults(Element root, BeanDefinitionParserDelegate parent) {
            //对dom的根文件(<beans>)默认初始化
            populateDefaults(this.defaults, (parent != null ? parent.defaults : null), root);
            //注册事件监听
            this.readerContext.fireDefaultsRegistered(this.defaults);
        }
    
       protected void populateDefaults(DocumentDefaultsDefinition defaults, DocumentDefaultsDefinition parentDefaults, Element root) {
            String lazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
            if (DEFAULT_VALUE.equals(lazyInit)) {
                // Potentially inherited from outer <beans> sections, otherwise falling back to false.
                lazyInit = (parentDefaults != null ? parentDefaults.getLazyInit() : FALSE_VALUE);
            }
            defaults.setLazyInit(lazyInit);
    
            String merge = root.getAttribute(DEFAULT_MERGE_ATTRIBUTE);
            if (DEFAULT_VALUE.equals(merge)) {
                // Potentially inherited from outer <beans> sections, otherwise falling back to false.
                merge = (parentDefaults != null ? parentDefaults.getMerge() : FALSE_VALUE);
            }
            defaults.setMerge(merge);
    
            String autowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE);
            if (DEFAULT_VALUE.equals(autowire)) {
                // Potentially inherited from outer <beans> sections, otherwise falling back to 'no'.
                autowire = (parentDefaults != null ? parentDefaults.getAutowire() : AUTOWIRE_NO_VALUE);
            }
            defaults.setAutowire(autowire);
    
            // Don't fall back to parentDefaults for dependency-check as it's no longer supported in
            // <beans> as of 3.0. Therefore, no nested <beans> would ever need to fall back to it.
            defaults.setDependencyCheck(root.getAttribute(DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE));
    
            if (root.hasAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE)) {
                defaults.setAutowireCandidates(root.getAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE));
            }
            else if (parentDefaults != null) {
                defaults.setAutowireCandidates(parentDefaults.getAutowireCandidates());
            }
    
            if (root.hasAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE)) {
                defaults.setInitMethod(root.getAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE));
            }
            else if (parentDefaults != null) {
                defaults.setInitMethod(parentDefaults.getInitMethod());
            }
    
            if (root.hasAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE)) {
                defaults.setDestroyMethod(root.getAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE));
            }
            else if (parentDefaults != null) {
                defaults.setDestroyMethod(parentDefaults.getDestroyMethod());
            }
    
            defaults.setSource(this.readerContext.extractSource(root));
        }
    
    

    相关文章

      网友评论

          本文标题:Spring源码解析(五)-XmlBeanDefinitionR

          本文链接:https://www.haomeiwen.com/subject/lzvdqxtx.html