Spring 系列(四)BeanFactory创建流程

PS: 查看源码的jar版本为 Spring-beans:5.2.15.release

1. 获取BeanFactory子流程

时序图

2. BeanDefinition加载解析及注册子流程

  1. 该子流程涉及如下几个关键步骤
  • Resource定位:指对BeanDefinition的资源定位过程。通俗里说就是找到定位JavaBean信息的XML文件,并将其封装成Resource对象。
  • BeanDefinition载入:把定义好的Javabean表示为IOC容器内部的数据结构,这个容器内部的数据结构就是BeanDefinition。
  • 注册BeanDefinition到IOC容器
  1. 过程分析

Step1:子流程入口在AbstractRefreshableApplicationContext#refreshBeanFactory
(从AbstractApplicationContext#refresh#obtainFreshBeanFactory()点进来)

//加载应用中的BeanDefinitions
            loadBeanDefinitions(beanFactory);

Step2:依次调⽤多个类的 loadBeanDefinitions ⽅法
—>AbstractXmlApplicationContext —>AbstractBeanDefinitionReader —>
XmlBeanDefinitionReader ⼀直执⾏到XmlBeanDefinitionReader 的 doLoadBeanDefinitions ⽅法

    try {
//读取xml信息,将xml信息保存到Document对象
            Document doc = doLoadDocument(inputSource, resource);
//解析document对象 封装BeanDefinition对象并进行注册
            int count = registerBeanDefinitions(doc, resource);
            if (logger.isDebugEnabled()) {
                logger.debug("Loaded " + count + " bean definitions from " + resource);
            }
            return count;
        }

Step3: 我们重点观察XmlBeanDefinitionReader 类的 registerBeanDefinitions ⽅法,期间产⽣了多次重载调⽤,我们定位到最后⼀个。(XmlBeanDefinitionReader#registerBeanDefinitions)

    public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
        BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
//获取已有BeanDefinition的数量
        int countBefore = getRegistry().getBeanDefinitionCount();
//注册BeanDefinition
        documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
//返回新注册的BeanDefinition的数量
        return getRegistry().getBeanDefinitionCount() - countBefore;
    }

此时我们关注两个地方:一个是createReaderContext方法 ,一个是 registerBeanDefinitions方法。
先进入createReaderContext方法看看

//1
    public XmlReaderContext createReaderContext(Resource resource) {
        return new XmlReaderContext(resource, this.problemReporter, this.eventListener,
                this.sourceExtractor, this, getNamespaceHandlerResolver());
    }
...
//2
    public NamespaceHandlerResolver getNamespaceHandlerResolver() {
        if (this.namespaceHandlerResolver == null) {
            this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver();
        }
        return this.namespaceHandlerResolver;
    }
...
//3
    protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
        ClassLoader cl = (getResourceLoader() != null ? getResourceLoader().getClassLoader() : getBeanClassLoader());
        return new DefaultNamespaceHandlerResolver(cl);
    }

我们可以看到,此处Spring首先完成了NamespaceHandlerResolver的初始化。
我们再进入registerBeanDefinitions方法中追踪,调用了DefaultBeanDefinitionDocumentReader#registerBeanDefinitionsf方法

    @Override
    public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
        this.readerContext = readerContext;
        doRegisterBeanDefinitions(doc.getDocumentElement());
    }

进入doRegisterBeanDefinitions方法



进入parseBeanDefinitions#parseDefaultElement方法



进入processBeanDefinition方法
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//解析bean元素为BeanDefinition,但此时使用BeanDefinitionHolder又包装成了BeanDefinitionHolder对象
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
//如果有自定义标签则处理自定义标签
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
            try {
                // 完成BeanDefinition的注册
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
            }

至此,注册流程结束,我们发现,所谓的注册就是把封装的XML中定义的Bean信息封装为BeanDefinition对象之后放入一个Map中,BeanFactory是以Map的结构组织这些BeanDefinition的。
DefaultListableBeanFactory#registerBeanDefinition

            // Still in startup registration phase
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                removeManualSingletonName(beanName);

可以在DefaultListableBeanFactory中看到此Map的定义

    /** Map of bean definition objects, keyed by bean name. */
    private final Map beanDefinitionMap = new ConcurrentHashMap<>(256);

  1. 时序图


    时序图

你可能感兴趣的:(Spring 系列(四)BeanFactory创建流程)