Spring源码分析第一集,IOC容器加载 - 千百度社区-后端论坛-技术交流-千百度社区

Spring源码分析第一集,IOC容器加载

Spring源码分析第一集,IOC容器加载

IOC容器介绍以及容器加载-当前只是简单对IOC加入的流程以及具体方法进行说明。后面补充每个方法的源码分析

在spring中,容器可以分为两大类。

  • 一类是由BeanFactory接口定义的核心容器,其基本的实现类为DefaultListableBaenFactory,之所以被称为核心容器,就是因为它实现了容器的核心功能,Bean的依赖注入以及生命周期的管理
  • 一类是由ApplicationContext接口定义的容器,也就是上下文。内部持有一个BeanFactory对象,它在BeanFactory上进行了拓展。例如国际化支持、事件监听、在开发中经常用到。

IOC启动流程

ClassPathXmlApplicationContext 入口
在使用ClassPathXmlApplicationContext构建IOC容器时,通常会传递配置文件。

public ClassPathXmlApplicationContext(
            String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
            throws BeansException {
        //传递上下文对象至父级容器
        super(parent);
        // 设置配置文件地址,等待后续创建容器时解析
        setConfigLocations(configLocations);
        // 判断是否刷新容器,默认为true
        if (refresh) {
            //开始构建并刷新容器
            refresh();
        }
    }

因为ClassPathXmlApplicationContext继承了AbstractApplicationContext所以最终会调用到AbstractApplicationContextrefresh方法。开始构建并刷新容器;refresh方法是整个IOC容器加载构建的最外层方法。

    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

            // 设置启动时间,并设置当前容器为活动状态,以及初始化环境变量
            prepareRefresh();
            // 构建BeanFactory工程。并解析之前设置的配置文件。生成BeanDefinition对象
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // 对BeanFactory工场的前置增强,内部
            prepareBeanFactory(beanFactory);

            try {
                // 对BeanFactory工程的后置增强。该方法可由子类实现。
                postProcessBeanFactory(beanFactory);

                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
                // 主要是对BeanDefinitionRegistryPostProcessor实例化,并运行postProcessBeanDefinitionRegistry与postProcessBeanFactory方法
                invokeBeanFactoryPostProcessors(beanFactory);

                // 主要是对BeanPostProcessors进行增强,但是不会允许其增强方法
                registerBeanPostProcessors(beanFactory);
                beanPostProcess.end();

                // 初始化国际化
                initMessageSource();

                // 初始化spring事件,默认使用SimpleApplicationEventMulticaster
                initApplicationEventMulticaster();

                // 扩展的一个实现 ,留给子类来初始化其它的Bean。如springboot内嵌的tomcat在这个阶段完成
                onRefresh();

                // 查询并注册所以的ApplicationListener到消息广播器中
                registerListeners();

                // 实例化所有的单例bean,在每个bean的实例化期间,都会调用前面注册的BeanPostProcess,进行前置后置增强
                finishBeanFactoryInitialization(beanFactory);

                // 发布相应的事件。完成刷新过程, 通知生命周期处现器lifecycleProcessor 刷新过程, 同时发出ContextRefreshEvent 通知别人
                finishRefresh();
            }

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

                // 销毁以创建的Bean
                destroyBeans();

                // 取消refresh操作,重置容器的同步标识
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                //重置Spring核心中的常见缓存,因为后面不再需要单例bean的元数据也就是。。。
                resetCommonCaches();
                contextRefresh.end();
            }
        }
    }

最后编辑于 : 2022.12.23 21:33:17 © 著作权归作者所有,转载或内容合作请联系作者

请登录后发表评论

    没有回复内容