1.1springioc启动源码分析(ClassPathXmlApplicationContext)

时间:2019-01-17
本文章向大家介绍1.1springioc启动源码分析(ClassPathXmlApplicationContext),主要包括1.1springioc启动源码分析(ClassPathXmlApplicationContext)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

spring启动源码分析(ClassPathXmlApplicationContext)

Applicantioncontext uml图

  1. ClassPathXmlApplicationContext xml 配置文件项目中的路径
  2. FileSystemXmlApplicationContext xml 配置文件在系统中的路径
  3. AnnotationConfigApplicationContext 注解类启动方式

BeanFactory uml图

  1. ApplicationContext 继承了 ListableBeanFactory,这个 Listable
    的意思就是,通过这个接口,我们可以获取多个 Bean,大家看源码会发现,最顶层 BeanFactory 接口的方法都是获取单个 Bean
    的。
  2. ApplicationContext 继承了 HierarchicalBeanFactory,Hierarchical
    单词本身已经能说明问题了,也就是说我们可以在应用中起多个 BeanFactory,然后可以将各个 BeanFactory设置为父子关系。
  3. AutowireCapableBeanFactory 这个名字中的 Autowire 大家都非常熟悉,它就是用来自动装配 Bean用的,但是上图ApplicationContext 并没有继承它。为了使用它,ApplicationContext 接口定义中的最后一个方法 getAutowireCapableBeanFactory()
  4. ConfigurableListableBeanFactory 也是一个特殊的接口,看图,特殊之处在于它继承了第二层所有的三个接口,而ApplicationContext 没有。这点之后会用到。

spring启动基本流程

  1. 调用spring容器准备刷新的方法,记录启动时间,设置active属性为true,closed为false;
  2. 初始化任务占位符属性
  3. 校验xml配置文件格式,
  4. 如果存在beanFactory和Bean,则删除,并创建DefaultListableBeanFactory
  5. 设置是否允许bean覆盖和循环引用
  6. 分割成xml数组,循环每一个xml配置文件,使用Threadlocal保证线程安全。
  7. inputStream读取xml配置文件并转为document对象(DeferredDocumentImpl),并从document对象获取DocumentElement并转为element对象(DeferredElementNSImpl)
  8. 获取element对象的ChildNodes(为Bean数组)并遍历该对象(有转回element类型)
  9. 分析每个element对象的bean定义元素,并封装成BeanDefinitionHolder,设置BeanDefinition,beanName,aliases[]别名数组。
  10. 根据beanName对Bean进行注册,处理重复beanName(是否允许循环引用);保存beanDefinitionMap<beanName,beanDefinition>;保存beanDefinitionNames保存在list;manualSingletonNames保存在LinkedHashSet;并注册bean别名 。
  11. (1)设置 BeanFactory 的类加载器,(2)初始化当前 ApplicationContext 的 MessageSource,(3)初始化当前 ApplicationContext 的事件广播器,(4)注册事件监听器,监听器需要实现 ApplicationListener 接口,
  12. 初始化Bean流程。
  13. 停止bean 定义解析、加载、注册;
  14. 循环beanDefinitionNames,对非抽象、非懒加载的 singleton Bean。
  15. 广播事件,ApplicationContext 初始化完成。

源码分析流程

public void refresh() throws BeansException, IllegalStateException {  
       synchronized (this.startupShutdownMonitor) {  
           //调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识  
           prepareRefresh();  
           //告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从  
          //子类的refreshBeanFactory()方法启动  
           ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  
           //为BeanFactory配置容器特性,例如类加载器、事件处理器等  
           prepareBeanFactory(beanFactory);  
           try {  
               //为容器的某些子类指定特殊的BeanPost事件处理器  
               postProcessBeanFactory(beanFactory);  
               //调用所有注册的BeanFactoryPostProcessor的Bean  
               invokeBeanFactoryPostProcessors(beanFactory);  
               //为BeanFactory注册BeanPost事件处理器.  
               //BeanPostProcessor是Bean后置处理器,用于监听容器触发的事件  
               registerBeanPostProcessors(beanFactory);  
               //初始化信息源,和国际化相关.  
               initMessageSource();  
               //初始化容器事件传播器.  
               initApplicationEventMulticaster();  
               //调用子类的某些特殊Bean初始化方法  
               onRefresh();  
               //为事件传播器注册事件监听器.  
               registerListeners();  
               //初始化所有剩余的单态Bean.  
               finishBeanFactoryInitialization(beanFactory);  
               //初始化容器的生命周期事件处理器,并发布容器的生命周期事件  
               finishRefresh();  
           }  
           catch (BeansException ex) {  
               //销毁以创建的单态Bean  
               destroyBeans();  
               //取消refresh操作,重置容器的同步标识.  
               cancelRefresh(ex);  
               throw ex;  
           }  
       }  
   }