spring源码01-容器启动流程介绍.md

本文基于spring xml配置方式,spring启动时的主要流程;下面会贴出代码,并说明重要方法的作用

一、spring容器的创建

//方法入口:
//构造spring容器并启动
ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");

//内部调用自身构造器
public ClassPathXmlApplicationContext(
        String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
        throws BeansException {

    // 一系列父类构造器调用过程,父类实例变量初始化
    // 其中在AbstractApplicationContext类中创建了PathMatchingResourcePatternResolver对象用于对传入的资源文件加载进行处理
    super(parent);
    /*
    创建系统环境变量和jvm环境变量属性对象,
    MutablePropertySources对象中存储了systemEnvironment(系统环境变量)、systemProperties(java启动参数)配置信息,
    并通过配置参数对传入的配置文件进行转换的过程,例如:application-${USER}.xml
    实现对${USER}的值处理过程,并把处理后的配置文件路径存储起来后续使用,
    转换过程是在PropertyPlaceholderHelper.parseStringValue方法实现的,不具体展开了。
    */
    setConfigLocations(configLocations);
    if (refresh) {
        // spring最重要的方法,调用父类AbstractApplicationContext.refresh()
        refresh();
    }
}

二、AbstractApplicationContext.refresh()方法

refresh方法是spring最重要的方法,包括ioc,aop,transaction等一系列功能的实现都在此方法;

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        /*
        1. 容器启动时间设置
        2. 容器启动标识设置为true
        3. 自定义属性配置加载,子类重写使用
        4. 必需的属性配置校验
        5. 父子容器,容器多次启动时的监听器配置工作
        */
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        /*
        1. 完成对BeanFactory的创建
        2. 完成对xml文件的加载,解析
        3. 根据xml配置生成BeanDefinition信息的创建和注册
        */
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        // 完成对beanFactory的配置工作,spel表达式处理类,环境配置对象的设置
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            // 留给子类重写使用的,可以做一些自定义的工作
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            // 完成对BeanFactoryPostProcess的调用(重要),
            // 通过时间BeanFactoryPostProcess接口可以对BeanDefinition信息进行增加,修改等处理操作
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            // 执行对BeanPostProcess接口实现类的查找,创建,并注册进容器。
            // 后续创建对象时使用这些类对象完成对待创建对象的扩展工作
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            //国际化i18n支持
            initMessageSource();

            // Initialize event multicaster for this context.
            // 完成事件多播器的注册,观察者模式,用来管理事件监听器
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            // 留给子类重写使用,便于扩展
            onRefresh();

            // Check for listener beans and register them.
            // 完成对事件监听器查找,创建,注册功能
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            /*
            1. 注册值转换服务;ConversionService 类型的转换
            2. 注册值处理器;${}占位符的处理
            3. 冻结BeanDefition配置信息
            4. 完成对单例对象的创建过程(过程中会触发对BeanPostProcess的调用)(重要)
            */
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            /*
            1. 完成资源的清理
            2. 完成对bean生命周期的处理工作
            3. 发布容器刷新时间
            */
            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();
        }
    }
}
posted @ 2023-02-27 17:52  铵铵静静  阅读(42)  评论(0编辑  收藏  举报