SpringBoot源码解读与原理分析(十三)IOC容器的启动流程

3.7 IOC容器的启动流程

SpringBoot源码解读与原理分析(八)ApplicationContext 中,梳理了是ApplicationContext的几个重要实现类,其中AbstractApplicationContext显得尤为重要:

ApplicationContext的几个重要实现类

ApplicationContext的启动,其内部的核心动作的刷新容器,也就是AbstractApplicationContext中的refresh()方法。

AbstractApplicationContext.java

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

        // Tell the subclass to refresh the internal bean factory.
        // 2.获取BeanFactory,加载所有bean的定义信息(未实例化)
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        // 3.BeanFactory的预处理配置
        prepareBeanFactory(beanFactory);

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

            // Invoke factory processors registered as beans in the context.
            // 5.执行BeanFactory创建后的后置处理器
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            // 6.注册Bean的后置处理器
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            // 7.初始化MessageSource
            initMessageSource();

            // Initialize event multicaster for this context.
            // 8.初始化事件广播器
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            // 9.子类的多态onRefresh
            onRefresh();

            // Check for listener beans and register them.
            // 10.注册监听器
            registerListeners();

            // 至此,BeanFactory创建完成

            // Instantiate all remaining (non-lazy-init) singletons.
            // 11.初始化所有剩下的单实例
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            // 12.完成容器的创建工作
            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...
            // 13.清理缓存
            resetCommonCaches();
        }
    }
}

整个refresh方法分为13步,这篇文章只是梳理每一步都做了哪些事情,对于其中的细节设计放到之后的文章再展开。

1.prepareRefresh——初始化前的预处理

/**
 * Prepare this context for refreshing, setting its startup date and
 * active flag as well as performing any initialization of property sources.
 */
protected void prepareRefresh() {
   
   
    // Switch to active.
    // 切换IOC容器启动状态
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);

    if (logger.isDebugEnabled()) {
   
   
        if (logger.isTraceEnabled()) {
   
   
            logger.trace("Refreshing " + this);
        } else {
   
   
            logger.debug("Refreshing " + getDisplayName());
        }
    }

    // Initialize any placeholder property sources in the context environment.
    // 在上下文环境中初始化任何占位符属性源
    initPropertySources();

    // Validate that all properties marked as required are resolvable:
    // see ConfigurablePropertyResolver#setRequiredProperties
    // 验证标记为required的所有属性都是可解析的
    getEnvironment().validateRequiredProperties();

    // Store pre-refresh ApplicationListeners...
    // 存储预刷新的ApplicationListeners
    if (this.earlyApplicationListeners == null) {
   
   
        this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    } else {
   
   
        // Reset local application listeners to pre-refresh state.
        // 将本地应用程序监听器重置为预刷新状态。
        this.applicationListeners.clear();
        this.applicationListeners.addAll(this.ea
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

维先生d

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值