Spring之BeanDefinitionParserDelegate源码解读

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】
免费领取 2000+ 道 Java 面试题

BeanDefinitionParserDelegate从字面意思上来看就是一个委托类,用来辅助解析bean的,这也确实是他的作用:
20191123100257\_1.png
下面我们就看一下这个类里面到底有什么东西

    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 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 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 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_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";

一开始就声明了各种常量字符串,都是在Spring的配置文件中常见的属性值。

    private final DocumentDefaultsDefinition defaults = new DocumentDefaultsDefinition();

接着,又是一个类,里面存了一个bean必须有的属性,没有就采用默认值。

    protected void populateDefaults(DocumentDefaultsDefinition defaults, @Nullable 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);

            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));
        }

填充各种默认的属性。

    public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
            //获取当前节点的id和name属性
            String id = ele.getAttribute(ID_ATTRIBUTE);
            String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
            //获取别名列表
            List<String> aliases = new ArrayList<>();
            if (StringUtils.hasLength(nameAttr)) {
                String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
                aliases.addAll(Arrays.asList(nameArr));
            }
            //如果id为空,且存在别名,那么把第一个别名当作beanName,并将他从别名列表中移除
            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);
            }
            //解析bean标签并封装成对象
            AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
            if (beanDefinition != null) {
            //如果beanName为空,那么么就根据指定的规则来创建一个beanName
                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);
                //返回一个封装了beanDefinition、beanName、aliasesArray的对象
                return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
            }

            return null;
        }

这个方法主要是处理了beanName和别名,具体解析属性在下面这个方法里面

    public AbstractBeanDefinition parseBeanDefinitionElement(
                Element ele, String beanName, @Nullable BeanDefinition containingBean) {

            this.parseState.push(new BeanEntry(beanName));

            String className = null;
            //解析class属性
            if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
                className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
            }
            String parent = null;
            //解析parent属性
            if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
                parent = ele.getAttribute(PARENT_ATTRIBUTE);
            }

            try {
                AbstractBeanDefinition bd = createBeanDefinition(className, parent);

                parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
                //设置描述符
                bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
                //解析其他属性
                parseMetaElements(ele, bd);
                parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
                parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

                parseConstructorArgElements(ele, bd);
                parsePropertyElements(ele, bd);
                parseQualifierElements(ele, 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;
        }

这个方法就是对各种属性的解析

    public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
                @Nullable BeanDefinition containingBean, AbstractBeanDefinition bd)

这个方法用来解析默认的属性
其余的方法都是对不同的标签提供的不同的方法,就不细加注释了。
BeanDefinitionParserDelegate类提供了解析spring配置文件功能,对于默认空间下的元素()在该类内部实现,对于其它命名空间下的元素可以通过绑定NamespaceHandler的方式来实现,针对每个命名空间下的元素提供不同BeanDefinitionParser来实现.


来源:http://ddrv.cn/a/88268

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » Spring之BeanDefinitionParserDelegate源码解读

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏