前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring源码学习笔记(12)——IoC容器启动流程

Spring源码学习笔记(12)——IoC容器启动流程

作者头像
张申傲
发布2020-09-03 11:25:40
3510
发布2020-09-03 11:25:40
举报
文章被收录于专栏:漫漫架构路漫漫架构路

Spring源码学习笔记(12)——IoC容器启动流程

本节主要详细分析IoC容器的启动和刷新流程

一. refresh()方法

IoC容器的启动和刷新方法在AbstractApplicationContext中定义,即refresh()方法:

代码语言:javascript
复制
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        //刷新前的准备工作
        prepareRefresh();

        //初始化并获取BeanFactory
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        //对刚创建好的BeanFactory进行一些预处理和设置
        prepareBeanFactory(beanFactory);

        try {
            //BeanFactory准备完成后的后置处理,空方法,交给子类实现
            postProcessBeanFactory(beanFactory);

            //执行容器中注册的BeanFactoryPostProcessor后处理器,先执行BeanDefinitionRegistryPostProcessor,再执行普通的BeanFactoryPostProcessor
            invokeBeanFactoryPostProcessors(beanFactory);

            //注册BeanPostProcessor后处理器,这里仅仅是注册,并没有执行实际的后处理逻辑
            registerBeanPostProcessors(beanFactory);

            //初始化MessageSource组件,处理国际化、消息绑定、消息解析等功能
            initMessageSource();

            //初始化ApplicationEventMulticaster事件分发器
            initApplicationEventMulticaster();

            //初始化其他特殊的Bean,空方法,交给子类实现
            onRefresh();

            //注册事件监听器
            registerListeners();

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

            //最后一步,完成刷新,发布容器刷新完成事件
            finishRefresh();
        }

        catch (BeansException ex) {
            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();
        }
    }
}

该方法内的一些处理在前面已经详细介绍过了,下面仅分析一下前面没有提及的方法。

二. prepareRefresh()

prepareRefresh()方法主要对容器的刷新进行一些预处理:

代码语言:javascript
复制
protected void prepareRefresh() {
    //记录容器的启动和关闭状态
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);

    if (logger.isInfoEnabled()) {
        logger.info("Refreshing " + this);
    }

    //初始化属性源配置,空方法,交给子类实现
    initPropertySources();

    //对一些自定义属性进行校验
    getEnvironment().validateRequiredProperties();

    //初始化早期事件集合, 在ApplicationEventMulticaster初始化完成之前发布的事件都在这里保存,一旦ApplicationEventMulticaster初始化完成,则一次性将这些早期时间全部发布
    this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}

三. obtainFreshBeanFactory()

代码语言:javascript
复制
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    //创建BeanFactory
    refreshBeanFactory();
    
    //获取刚才创建的BeanFactory
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (logger.isDebugEnabled()) {
        logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
    }
    return beanFactory;
}

四. prepareBeanFactory()

代码语言:javascript
复制
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    //设置BeanFactory的类加载器、表达式解析器等
    beanFactory.setBeanClassLoader(getClassLoader());
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    //添加一些BeanPostProcessor
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    
    //设置一些忽略自动装配的接口,这些接口的实现类不支持自动注入
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

    //注册可以解析的自动装配,这些组件可直接使用@Autowired自动注入
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    //添加LoadTimeWeaverAwareProcessor后处理器
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        // Set a temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    //注册一些环境相关的Bean,这些Bean也可以使用@Autowired直接注入
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
}

五. initMessageSource()

代码语言:javascript
复制
protected void initMessageSource() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    //检查当前容器中是否存在beanName为messageSource,如果存在,直接获取并赋值给成员变量
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
        this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
        if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
            HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
            if (hms.getParentMessageSource() == null) {
                hms.setParentMessageSource(getInternalParentMessageSource());
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Using MessageSource [" + this.messageSource + "]");
        }
    }
    //如果容器中不存在,则创建DelegatingMessageSource实例并注册到容器中
    else {
        DelegatingMessageSource dms = new DelegatingMessageSource();
        dms.setParentMessageSource(getInternalParentMessageSource());
        this.messageSource = dms;
        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
                         "': using default [" + this.messageSource + "]");
        }
    }
}

六. finishBeanFactoryInitialization()

代码语言:javascript
复制
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    //初始化类型转换器
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
        beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }

    //初始化LoadTimeWeaverAware
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    //停止使用TempClassLoader
    beanFactory.setTempClassLoader(null);

    beanFactory.freezeConfiguration();

    //初始化剩余的单实例Bean(非lazy-init的)
    beanFactory.preInstantiateSingletons();
}

七. finishRefresh()

代码语言:javascript
复制
protected void finishRefresh() {
    //初始化生命周期相关的后处理器LifecycleProcessor,LifecycleProcessor可以在容器的刷新完成和关闭时收到回调,进行额外的处理:onRefresh()和onClose()方法。默认使用DefaultLifecycleProcessor
    initLifecycleProcessor();

    //回调LifecycleProcessor的onRefresh()
    getLifecycleProcessor().onRefresh();

    //发布容器刷新完成事件ContextRefreshedEvent
    publishEvent(new ContextRefreshedEvent(this));

    //处理LiveBeansView
    LiveBeansView.registerApplicationContext(this);
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-10-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring源码学习笔记(12)——IoC容器启动流程
    • 一. refresh()方法
      • 二. prepareRefresh()
        • 三. obtainFreshBeanFactory()
          • 四. prepareBeanFactory()
            • 五. initMessageSource()
              • 六. finishBeanFactoryInitialization()
                • 七. finishRefresh()
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档