• 读spring源码(一)-ClassPathXmlApplicationContext-初始化


    工作来几乎所有的项目都用到了spring,却一直没有系统的读下源码,从头开始系统的读下吧,分章也不那么明确,读到哪里记到哪里,仅仅作为个笔记吧。

    先看ClassPathXmlApplicationContext的类图

    有人说:BeanFactory是Spring的心脏,ApplicationContext就是完整的躯体。ApplicationContext继承了BeanFactory,ResourceLoader提供了类的管理以及资源的加载,同时又继承了EnvironmentCapable,MessageSource, ApplicationEventPublisher等,将环境、消息、事件等统一管理,真是的算上一个完整的躯干了。

    简单使用:

            ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:META-INF/spring/test-spring.xml");
            User user = context.getBean(User.class);
            System.out.println(user.getId());

     ApplicationContext的初始化时序图如下:

    1、super(parent)调用父类构造函数,在AbstractApplicationContext中会初始化resourcePatternResolver。

    2、setConfigLocations(configLocations)解析spring的配置文件地址,设置到configLocations。

    3、refresh()这是ApplicationContext初始化的核心,会在这里初始化BeanFactory,解析XML加载BeanDefinition,注册bean处理器,注册事件添加监听等

    3.1 prepareRefresh(),初始化基础属性值
    3.2 obtainFreshBeanFactory(),这里会再执行refreshBeanFactory时候创建一个默认的BeanFactory:DefaultListableBeanFactory,并加载BeanDefinition。
    加载BeanDefinition是会创建一个XmlBeanDefinitionReader对象,交由XmlBeanDefinitionReader去进行加载。这里处理的比较复杂后面单独分析下XmlBeanDefinitionReader。
    3.3 prepareBeanFactory(beanFactory),为beanFactory设置一些属性如ClassLoader,BeanExpressionResolver,PropertyEditorRegistrar,BeanPostProcessor等
    3.4 invokeBeanFactoryPostProcessors(beanFactory),为beanFactory注册BeanFactoryPostProcessor
    3.5 registerBeanPostProcessors(beanFactory),注册当Bean创建时候的BeanPostProcessor
    3.6 initMessageSource()初始化上下文的消息源:DelegatingMessageSource
    3.7 initApplicationEventMulticaster()初始化了一个事件传播器:SimpleApplicationEventMulticaster
    3.8 registerListeners()获取ApplicationListener,并在事件传播器中注册他们
    3.9 finishBeanFactoryInitialization(beanFactory),获取LoadTimeWeaverAware并初始化他们,初始化单例并且非懒加载的Bean
    3.10 finishRefresh()完成refresh Context操作,初始化LifecycleProcessor并start,发布ContextRefreshedEvent事件
    3.11 resetCommonCaches()主要是清理缓存

    一个ClassPathXmlApplicationContext的初始化过程基本如上,详细的BeanDefinition加载过程,获取Bean操作后续再写吧。

  • 相关阅读:
    块存储、文件存储、对象存储的区别
    brk 和 sbrk 区别
    【转】海量数据处理:十道面试题与十个海量数据处理方法总结
    C++ STL 里为什么不维护一个 size 成员变量?
    C++对象内存分布详解(包括字节对齐和虚函数表)
    虚函数实现原理
    关于Ubuntu中Could not get lock /var/lib/dpkg/lock解决方案
    Jerasure 1.2A 中的 C 函数 tips
    C++ qsort() 函数调用时实参与形参不兼容的问题解决
    C语言位运算符:与、或、异或、取反、左移与右移详细介绍
  • 原文地址:https://www.cnblogs.com/lcxdever/p/9281140.html
Copyright © 2020-2023  润新知