Spring源码:注册bean——XmlBeanDefinitionReader.registerBeanDefinitions(Documnt doc, Resource resouce)

目录

1、截取 XmlBeanDefinitionReader.registerBeanDefinitions(Documnt doc, Resource resouce) 部分代码

2、XmlReaderContext、DefaultNamespaceHandlerResolver 

3、加载及注册bean,委托给 DefaultBeanDefinitionDocumentReader

DefaultBeanDefinitionDocumentReader 源码

BeanDefinitionReaderUtils 源码

DefaultListableBeanFactory 源码

4、getBean 的过程


1、截取 XmlBeanDefinitionReader.registerBeanDefinitions(Documnt doc, Resource resouce) 部分代码

代码如下


public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {

    private Class<? extends BeanDefinitionDocumentReader> documentReaderClass = DefaultBeanDefinitionDocumentReader.class;
    private ProblemReporter problemReporter = new FailFastProblemReporter();
    private ReaderEventListener eventListener = new EmptyReaderEventListener();
    private SourceExtractor sourceExtractor = new NullSourceExtractor();
    @Nullable
    private NamespaceHandlerResolver namespaceHandlerResolver;

    // 在AbstractBeanDefinitionReader类继承的代码,这里写在这里加深理解  start
    private final BeanDefinitionRegistry registry;
    public final BeanDefinitionRegistry getRegistry() {
        return this.registry;
    }
    // 在AbstractBeanDefinitionReader类继承的代码,这里写在这里加深理解  end
    
    /**
    * doc:xml配置文件解析后的Document
    * resource:配置文件资源
    *
    */
    public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
        BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
        /**
        * 获取BeanDefinitionRegistry接口,getBeanDefinitionCount方法在
        * DefaultListableBeanFactory 实现了,代码如下
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);
public int getBeanDefinitionCount() {
        return this.beanDefinitionMap.size();
    }
        * beanDefinitionMap 实际就是注册BeanDefinition的容器,这里主要用于获取已经注册的 BeanDefinition 数量
        */
        int countBefore = this.getRegistry().getBeanDefinitionCount();
        // 核心方法,加载及注册 bean,委托给 DefaultBeanDefinitionDocumentReader 来处理
        // this.createReaderContext:生成xmlreader的上下文context,其中有配置好的命名空间
        documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
        return this.getRegistry().getBeanDefinitionCount() - countBefore;
    }
    // 创建 DefaultBeanDefinitionDocumentReader
    protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {
        return (BeanDefinitionDocumentReader)BeanUtils.instantiateClass(this.documentReaderClass);
    }

    // 生成xmlreader的上下文context,其中有配置好的命名空间
    public XmlReaderContext createReaderContext(Resource resource) {
        return new XmlReaderContext(resource, this.problemReporter, this.eventListener, this.sourceExtractor, this, this.getNamespaceHandlerResolver());
    }
    // 获取命名空间的处理器
    public NamespaceHandlerResolver getNamespaceHandlerResolver() {
        if(this.namespaceHandlerResolver == null) {
            this.namespaceHandlerResolver = this.createDefaultNamespaceHandlerResolver();
        }

        return this.namespaceHandlerResolver;
    }

    protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
        ClassLoader cl = this.getResourceLoader() != null?this.getResourceLoader().getClassLoader():this.getBeanClassLoader();
        // 命名空间处理器,待了解
        return new DefaultNamespaceHandlerResolver(cl);
    }
}

2、XmlReaderContext、DefaultNamespaceHandlerResolver 

//TODO

3、加载及注册bean,委托给 DefaultBeanDefinitionDocumentReader

DefaultBeanDefinitionDocumentReader 源码

 

package org.springframework.beans.factory.xml;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.LinkedHashSet;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

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) {
        // 这个readerContext就是上面传进来的读取xml的context上下文
        this.readerContext = readerContext;
        // doc.getDocumentElement() 获取 XML 的根节点root,传入方法内
        this.doRegisterBeanDefinitions(doc.getDocumentElement());
    }

    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);
    }
    
    // 根节点传入解析
    protected void doRegisterBeanDefinitions(Element root) {
        // Delegate 中文解释 委托
        // BeanDefinitionParserDelegate 解释 BeanDefinition委托解析类
        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)) {
                    if(this.logger.isDebugEnabled()) {
                        this.logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + this.getReaderContext().getResource());
                    }

                    return;
                }
            }
        }
        // 模板方法
        this.preProcessXml(root);
        // 核心方法:正式解析生成 BeanDefinition
        this.parseBeanDefinitions(root, this.delegate);
        // 模板方法
        this.postProcessXml(root);
        // 保留委托类,省的重复创建
        this.delegate = parent;
    }
    // 创建 BeanDefinitionParserDelegate:https://blog.csdn.net/ruanhao1203/article/details/103504087
    protected BeanDefinitionParserDelegate createDelegate(XmlReaderContext readerContext, Element root, @Nullable BeanDefinitionParserDelegate parentDelegate) {
        BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext);
        delegate.initDefaults(root, parentDelegate);
        return delegate;
    }
    // 解析并生成 BeanDefinition
    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        // 判断命名空间是不是 spring默认的:http://www.springframework.org/schema/beans
        if(delegate.isDefaultNamespace(root)) {
            // 获取 beans 下所有 bean标签,也可能是其他标签,这里以bean为例
            NodeList nl = root.getChildNodes();

            for(int i = 0; i < nl.getLength(); ++i) {
                // 单个bean标签
                Node node = nl.item(i);
                if(node instanceof Element) {
                    Element ele = (Element)node;
// 判断命名空间是不是 spring默认的:http://www.springframework.org/schema/beans
                    if(delegate.isDefaultNamespace(ele)) {
                        // spring默认命名空间下 元素解析
                        this.parseDefaultElement(ele, delegate);
                    } else {// 自定义命名空间解析
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        } else {// 自定义命名空间解析
            delegate.parseCustomElement(root);
        }

    }
    // spring默认命名空间下 元素解析
    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")) {// bean标签解析
            this.processBeanDefinition(ele, delegate);
        } else if(delegate.nodeNameEquals(ele, "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<Resource> 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.isTraceEnabled()) {
                        this.logger.trace("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.isTraceEnabled()) {
                        this.logger.trace("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) {
        // 解析过程参考parseBeanDefinitionElement:https://blog.csdn.net/ruanhao1203/article/details/103504087
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if(bdHolder != null) {
            // 
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

            try {
                // 注册bean
                // this.getReaderContext.getRegistry():获取BeanDefinitionRegistry
                // BeanDefinitionReaderUtils 继续往下看
                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) {
    }
}

BeanDefinitionReaderUtils 源码

 

package org.springframework.beans.factory.support;

import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

public abstract class BeanDefinitionReaderUtils {
    public static final String GENERATED_BEAN_NAME_SEPARATOR = "#";

    public BeanDefinitionReaderUtils() {
    }
    // 创建 BeanDefinition,被上一个类源码调用
    public static AbstractBeanDefinition createBeanDefinition(@Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {
        GenericBeanDefinition bd = new GenericBeanDefinition();
        bd.setParentName(parentName);
        if(className != null) {
            if(classLoader != null) {
                bd.setBeanClass(ClassUtils.forName(className, classLoader));
            } else {
                bd.setBeanClassName(className);
            }
        }

        return bd;
    }

    public static String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
        return generateBeanName(beanDefinition, registry, false);
    }

    public static String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry, boolean isInnerBean) throws BeanDefinitionStoreException {
        String generatedBeanName = definition.getBeanClassName();
        if(generatedBeanName == null) {
            if(definition.getParentName() != null) {
                generatedBeanName = definition.getParentName() + "$child";
            } else if(definition.getFactoryBeanName() != null) {
                generatedBeanName = definition.getFactoryBeanName() + "$created";
            }
        }

        if(!StringUtils.hasText(generatedBeanName)) {
            throw new BeanDefinitionStoreException("Unnamed bean definition specifies neither 'class' nor 'parent' nor 'factory-bean' - can't generate bean name");
        } else if(isInnerBean) {
            String id = generatedBeanName + "#" + ObjectUtils.getIdentityHexString(definition);
            return id;
        } else {
            return uniqueBeanName(generatedBeanName, registry);
        }
    }

    public static String uniqueBeanName(String beanName, BeanDefinitionRegistry registry) {
        String id = beanName;

        for(int counter = -1; counter == -1 || registry.containsBeanDefinition(id); id = beanName + "#" + counter) {
            ++counter;
        }

        return id;
    }

    /**
    * 注册bean 到 DefaultListableBeanFactory 中
    *
    *
    */
    public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
        // bean标签 id值,例如user
        String beanName = definitionHolder.getBeanName();
        // BeanDefinitionRegistry的registerBeanDefinition方法注册bean,此接口方法在 DefaultListableBeanFactory 实现,代码请看下一个源码
        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);
            }
        }

    }

    public static String registerWithGeneratedName(AbstractBeanDefinition definition, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
        String generatedName = generateBeanName(definition, registry, false);
        registry.registerBeanDefinition(generatedName, definition);
        return generatedName;
    }
}

DefaultListableBeanFactory 源码

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    
    // BeanDefinition 容器
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);
    // BeanDefinition 对应 id的容器
    private volatile List<String> beanDefinitionNames = new ArrayList(256);

    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 var8) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var8);
            }
        }
        
        BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
        // 判断是否已存在
        if(existingDefinition != null) {
            if(!this.isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
            }

            if(existingDefinition.getRole() < beanDefinition.getRole()) {
                if(this.logger.isInfoEnabled()) {
                    this.logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
                }
            } else if(!beanDefinition.equals(existingDefinition)) {
                if(this.logger.isDebugEnabled()) {
                    this.logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
                }
            } else if(this.logger.isTraceEnabled()) {
                this.logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] 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;
                    this.removeManualSingletonName(beanName);
                }
            } else {
                // 核心:把BeanDefinition放入容器
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                this.removeManualSingletonName(beanName);
            }

            this.frozenBeanDefinitionNames = null;
        }

        if(existingDefinition != null || this.containsSingleton(beanName)) {
            this.resetBeanDefinition(beanName);
        }

    }
}

至此 bean 加载注册过程就结束了。

4、getBean 的过程

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值