Loading

Spring Ioc容器初始化流程

主要介绍一下SpringIoc容器初始化主流程
结合源码分析下核心的BeanFactory创建子流程和Bean创建子流程

org.springframework.context.support.AbstractApplicationContext#refresh

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        // 刷新前的预处理
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        // 获取BeanFactory默认获取DefaultListableBeanFactory
        // 加载BeanDefinition到BeanDefitionRegistry
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        // BeanFactory的预准备工作(BeanFactory进行一些设置,比如context的类加 载器等)
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            // BeanFactory准备工作完成后进行的后置处理工作
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            // 实例化并调用实现了BeanFactoryPostProcessor接口的Bean
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            // 注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执行
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            // 初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
            initMessageSource();

            // Initialize event multicaster for this context.
            // 初始化事件派发器
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            // 预留给子类重写这个方法,在容器刷新的时候可以自定义逻辑
            onRefresh();

            // Check for listener beans and register them.
            // 注册应用的监听器。就是注册实现了ApplicationListener接口的监听器
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            // 初始化所有剩下的非懒加载的单例bean.
            // 		初始化创建非懒加载方式的单例Bean实例(未设置属性)
            // 		填充属性
            // 		初始化方法调用(比如调用afterPropertiesSet方法、init-method方法)
            // 		调用BeanPostProcessor(后置处理器)对实例bean进行后置处
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            // 完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法,并且发布事件
            finishRefresh();
        }

        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
            }

            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();

            // Reset 'active' flag.
            cancelRefresh(ex);

            // Propagate exception to caller.
            throw ex;
        }

        finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

从源码看初始化关键的流程主要为(只列出了核心流程,在以下流程中还穿插了一些其他流程避免混乱未列出

  1. 获取BeanFactory
  2. 加载BeanDefinition
  3. 加载BeanFactoryPostProcessors
  4. 执行BeanFactoryPostProcessors
  5. 注册BeanPostProcessor
  6. 加载非懒加载单例Bean
    1. bean初始化
    2. 初始化方法调用
    3. 调用BeanPostProcessor的before、after方法

创建BeanFactory

获取BeanFactory

org.springframework.context.support.AbstractApplicationContext#obtainFreshBeanFactory为获取BeanFactory的入口

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory();
}

org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory

protected final void refreshBeanFactory() throws BeansException {
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        // 创建BeanFactory
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        beanFactory.setSerializationId(getId());
        customizeBeanFactory(beanFactory);
        loadBeanDefinitions(beanFactory);
        synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

从源代码可以看出主要是由createBeanFactory()实现创建BeanFactory,默认创建DefaultListableBeanFactory类型
调用时序图如下:
image.png

加载BeanDefinition

主要流程分为:Resource定位、加载BeanDefinition、注册BeanDefinition

入口在org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory调用的loadBeanDefinitions()

通过断点调试发现
loadBeanDefinitions() -> AbstractXmlApplicationContext.class -> AbstractBeanDefinitionReader.class -> XmlBeanDefinitionReader.class一直到执行XmlBeanDefinitionReader#doLoadBeanDefinitions()
image.png

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
    throws BeanDefinitionStoreException {

    try {
        // 加载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;
    }
    catch (BeanDefinitionStoreException ex) {
        // 代码过多为了清晰省略,主要是异常捕获
        ... 
    }
}

再进入 registerBeanDefinitions 方法中追踪,调用了DefaultBeanDefinitionDocumentReader#registerBeanDefinitions方法

DefaultBeanDefinitionDocumentReader.class
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    int countBefore = getRegistry().getBeanDefinitionCount();
    // 注册BeanDefinition
    documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
    return getRegistry().getBeanDefinitionCount() - countBefore;
}
DefaultBeanDefinitionDocumentReader.class
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;
    this.delegate = createDelegate(getReaderContext(), root, parent);

    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);
            // We cannot use Profiles.of(...) since profile expressions are not supported
            // in XML config. See SPR-12458 for details.
            if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
                                 "] not matching: " + getReaderContext().getResource());
                }
                return;
            }
        }
    }

    // 预留给子类的钩子函数
    preProcessXml(root);
    // 具体的解析和加载
    parseBeanDefinitions(root, this.delegate);
    // 预留给子类的钩子函数
    postProcessXml(root);

    this.delegate = parent;
}
DefaultBeanDefinitionDocumentReader.class
/**
	 * Parse the elements at the root level in the document:
	 * "import", "alias", "bean".
	 * @param root the DOM root element of the document
	 */
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    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)) {
                    // 核心逻辑
                    parseDefaultElement(ele, delegate);
                }
                else {
                    delegate.parseCustomElement(ele);
                }
            }
        }
    }
    else {
        delegate.parseCustomElement(root);
    }
}
DefaultBeanDefinitionDocumentReader.class
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
        importBeanDefinitionResource(ele);
    }
    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
        processAliasRegistration(ele);
    }
    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
        processBeanDefinition(ele, delegate);
    }
    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
        // recurse
        doRegisterBeanDefinitions(ele);
    }
}
DefaultBeanDefinitionDocumentReader.class
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
        try {
            // Register the final decorated instance.
            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
        }
        catch (BeanDefinitionStoreException ex) {
            getReaderContext().error("Failed to register bean definition with name '" +
                                     bdHolder.getBeanName() + "'", ele, ex);
        }
        // Send registration event.
        getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
}

从上面的源码一路跟踪下来是在org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseDefaultElement中判断解析具体标签,以BEAN为例子:

  1. 通过BeanDefinitionParserDelegate.parseBeanDefinitionElement(ele) 解析封装成BeanDefinitionHolder对象
  2. 通过BeanDefinitionReaderUtils.registerBeanDefinition注册bean
BeanDefinitionReaderUtils
public static void registerBeanDefinition(
    BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
    throws BeanDefinitionStoreException {

    // Register bean definition under primary name.
    String beanName = definitionHolder.getBeanName();
    // 注册beanDefinition
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

    // Register aliases for bean name, if any.
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
        for (String alias : aliases) {
            registry.registerAlias(beanName, alias);
        }
    }
}

image.png
整个注册的最终流程是将BeanDefinition放入到BeanFatory的beanDefinitionMap中。
image.png

Bean创建流程

  • bean创建子流程的入口在org.springframework.context.support.AbstractApplicationContext#refresh的finishBeanFactoryInitializationimage.png
  • 进入finishBeanFactoryInitialization

image.png

  • debug跟踪代码最终是在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean真正开始创建bean

image.png

  1. DefaultListableBeanFactory#preInstantiateSingletons
  2. AbstractBeanFactory#getBean(java.lang.String)
  3. AbstractBeanFactory#doGetBean
  4. DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
  5. AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
  6. AbstractAutowireCapableBeanFactory#doCreateBean
  • 分析doCreateBean
    • 创建bean实例 但是未设置属性

image.png

  • 设置属性,应用beanPostProcessor后置处理器

image.png

posted @ 2021-12-18 14:24  Vic呼叫89  阅读(41)  评论(0)    收藏  举报