源码:DefaultBeanDefinitionDocumentReader 注册 Bean

目录

1、概述

2、代码分析


1、概述

DefaultBeanDefinitionDocumentReader的 doRegisterBeanDefinitions(Element root) 是真正解析 Spring配置文件的各种元素,转化成 BeanDefinition 的过程。

2、代码分析

DefaultBeanDefinitionDocumentReader 代码如下

package org.springframework.beans.factory.xml;

public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {
    public static final String BEAN_ELEMENT = "bean";
    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(this.getClass());
    @Nullable
    private XmlReaderContext readerContext;
    @Nullable
    private BeanDefinitionParserDelegate delegate;

    public DefaultBeanDefinitionDocumentReader() {
    }

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

    protected final XmlReaderContext getReaderContext() {
        Assert.state(this.readerContext != null, "No XmlReaderContext available");
        return this.readerContext;
    }

    @Nullable
    protected Object extractSource(Element ele) {
        return this.getReaderContext().extractSource(ele);
    }

// 解析各种xml元素,转换为 BeanDefinition的方法
    protected void doRegisterBeanDefinitions(Element root) {
// 委托解析辅助类
        BeanDefinitionParserDelegate parent = this.delegate;
// 创建委托解析辅助类
        this.delegate = this.createDelegate(this.getReaderContext(), root, parent);
        if (this.delegate.isDefaultNamespace(root)) {
// profile支持
            String profileSpec = root.getAttribute("profile");
            if (StringUtils.hasText(profileSpec)) {
                String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; ");
                if (!this.getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
                    if (this.logger.isInfoEnabled()) {
                        this.logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + this.getReaderContext().getResource());
                    }

                    return;
                }
            }
        }
// 前置空方法
        this.preProcessXml(root);
// 解析方法
        this.parseBeanDefinitions(root, this.delegate);
// 后置空方法
        this.postProcessXml(root);
        this.delegate = parent;
    }

    protected BeanDefinitionParserDelegate createDelegate(XmlReaderContext readerContext, Element root, @Nullable BeanDefinitionParserDelegate parentDelegate) {
        BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext);
        delegate.initDefaults(root, parentDelegate);
        return delegate;
    }

    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
// 判断是否为Spring默认命名空间
        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")) {// import标签解析,实际是加载另一个Spring配置文件,然后再循环解析
            this.importBeanDefinitionResource(ele);
        } else if (delegate.nodeNameEquals(ele, "alias")) {// 别名解析
            this.processAliasRegistration(ele);
        } else if (delegate.nodeNameEquals(ele, "bean")) {// bean解析
            this.processBeanDefinition(ele, delegate);
        } else if (delegate.nodeNameEquals(ele, "beans")) {// beans解析,实际还是循环解析
            this.doRegisterBeanDefinitions(ele);
        }

    }

    protected void importBeanDefinitionResource(Element ele) {
        String location = ele.getAttribute("resource");
        if (!StringUtils.hasText(location)) {
            this.getReaderContext().error("Resource location must not be empty", ele);
        } else {
            location = this.getReaderContext().getEnvironment().resolveRequiredPlaceholders(location);
            Set actualResources = new LinkedHashSet(4);
            boolean absoluteLocation = false;

            try {
                absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();
            } catch (URISyntaxException var11) {
                ;
            }

            int importCount;
            if (absoluteLocation) {
                try {
                    importCount = this.getReaderContext().getReader().loadBeanDefinitions(location, actualResources);
                    if (this.logger.isDebugEnabled()) {
                        this.logger.debug("Imported " + importCount + " bean definitions from URL location [" + location + "]");
                    }
                } catch (BeanDefinitionStoreException var10) {
                    this.getReaderContext().error("Failed to import bean definitions from URL location [" + location + "]", ele, var10);
                }
            } else {
                try {
                    Resource relativeResource = this.getReaderContext().getResource().createRelative(location);
                    if (relativeResource.exists()) {
                        importCount = this.getReaderContext().getReader().loadBeanDefinitions(relativeResource);
                        actualResources.add(relativeResource);
                    } else {
                        String baseLocation = this.getReaderContext().getResource().getURL().toString();
                        importCount = this.getReaderContext().getReader().loadBeanDefinitions(StringUtils.applyRelativePath(baseLocation, location), actualResources);
                    }

                    if (this.logger.isDebugEnabled()) {
                        this.logger.debug("Imported " + importCount + " bean definitions from relative location [" + location + "]");
                    }
                } catch (IOException var8) {
                    this.getReaderContext().error("Failed to resolve current resource location", ele, var8);
                } catch (BeanDefinitionStoreException var9) {
                    this.getReaderContext().error("Failed to import bean definitions from relative location [" + location + "]", ele, var9);
                }
            }

            Resource[] actResArray = (Resource[])actualResources.toArray(new Resource[0]);
            this.getReaderContext().fireImportProcessed(location, actResArray, this.extractSource(ele));
        }
    }

    protected void processAliasRegistration(Element ele) {
        String name = ele.getAttribute("name");
        String alias = ele.getAttribute("alias");
        boolean valid = true;
        if (!StringUtils.hasText(name)) {
            this.getReaderContext().error("Name must not be empty", ele);
            valid = false;
        }

        if (!StringUtils.hasText(alias)) {
            this.getReaderContext().error("Alias must not be empty", ele);
            valid = false;
        }

        if (valid) {
            try {
                this.getReaderContext().getRegistry().registerAlias(name, alias);
            } catch (Exception var6) {
                this.getReaderContext().error("Failed to register alias '" + alias + "' for bean with name '" + name + "'", ele, var6);
            }

            this.getReaderContext().fireAliasRegistered(name, alias, this.extractSource(ele));
        }

    }
// bean 标签解析
    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 委托类解析 bean元素 为 BeanDefinitionHolder
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

            try {
// 实际是调用 DefaultListableBeanFactory 实现 BeanDefinitionRegistry 的注册 Bean 方法
                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));
        }

    }

    protected void preProcessXml(Element root) {
    }

    protected void postProcessXml(Element root) {
    }
}

        注册Bean 

你可能感兴趣的:(Spring)