Spring启动流程概述

Spring的IoC容器在实现控制反转和依赖注入的过程中,可以划分为两个阶段:

  • 容器启动阶段
  • Bean实例化阶段

容器初始化

  1. 加载配置
  2. 分析配置信息
  3. 将Bean信息装配到BeanDefinition
  4. 将Bean信息注册到相应的BeanDefinitionRegistry
  5. 其他后续处理

容器实例化

  1. 根据策略实例化对象
  2. 装配依赖
  3. Bean初始化前处理
  4. 对象初始化
  5. 对象其他处理
  6. 注册回调接口

启动流程源码概览

在这里插入图片描述

ClassPathXmlApplicationContext

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
			throws BeansException {
    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        refresh();
    }
}

public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz, ApplicationContext parent)
			throws BeansException {
    super(parent);
    Assert.notNull(paths, "Path array must not be null");
    Assert.notNull(clazz, "Class argument must not be null");
    this.configResources = new Resource[paths.length];
    for (int i = 0; i < paths.length; i++) {
        this.configResources[i] = new ClassPathResource(paths[i], clazz);
    }
    refresh();
}

AbstractApplicationContext

public void refresh() throws BeansException, IllegalStateException {
    // 方法加锁避免多线程同时刷新Spring上下文
    synchronized (this.startupShutdownMonitor) {
        // 准备上下文刷新
        prepareRefresh();

        // 告诉子类刷新内部的beanFactory返回新的BeanFactory
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // 在当前上下文中准备要beanFactory
        prepareBeanFactory(beanFactory);

        try {
            // 允许在上下文子类中对beanFactory进行后置处理
            postProcessBeanFactory(beanFactory);

            // 在上下文中将BeanFactory处理器注册为Bean
            invokeBeanFactoryPostProcessors(beanFactory);

            // 注册Bean处理器用于拦截Bean的创建
            registerBeanPostProcessors(beanFactory);

            // 在上下文中初始化国际化信息
            initMessageSource();

            // 在上下文中初始化event multicaster(事件多播器)
            initApplicationEventMulticaster();

            // 在指定的上下文子类中初始化其他指定的beans
            onRefresh();

            // 检查并注册事件监听
            registerListeners();

            // 实例化所有剩余的(非延迟初始化)单例
            finishBeanFactoryInitialization(beanFactory);

            // 最后一步:发布相应的事件
            finishRefresh();
        }
        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                    "cancelling refresh attempt: " + ex);
            }

            // 如果出现异常则销毁已创建的单例
            destroyBeans();

            // 重置活动标志。
            cancelRefresh(ex);

            // 将异常传递给调用者
            throw ex;
        }
        finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

整个refresh()的代码都是同步的,而对应的同步对象是startupShutdownMonitor。startupShutdownMonitor只在refresh()和close()两个方法里被用到,它是用来同步applicationContext的刷新和销毁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值