zoukankan      html  css  js  c++  java
  • spring源码

    https://blog.csdn.net/sinat_16658263/article/details/104602550

    public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
      private Resource[] configResources;
     
      // 如果已经有 ApplicationContext 并需要配置成父子关系,那么调用这个构造方法
      public ClassPathXmlApplicationContext(ApplicationContext parent) {
        super(parent);
      }
      ...
      public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
          throws BeansException {
     
        super(parent);
        // 根据提供的路径,处理成配置文件数组(以分号、逗号、空格、tab、换行符分割)
        setConfigLocations(configLocations);
        if (refresh) {
          refresh(); // 核心方法
        }
      }
        ...
    }

     

    refresh()

    @Override
    public void refresh() throws BeansException, IllegalStateException {
       // 来个锁,不然 refresh() 还没结束,你又来个启动或销毁容器的操作,那不就乱套了嘛
       synchronized (this.startupShutdownMonitor) {
     
          // 准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
          prepareRefresh();
     
          // 这步比较关键,这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,
          // 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
          // 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
          ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
     
          // 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
          // 这块待会会展开说
          prepareBeanFactory(beanFactory);
     
          try {
             // 【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
             // 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】
     
             // 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
             // 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
             postProcessBeanFactory(beanFactory);
             // 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
             invokeBeanFactoryPostProcessors(beanFactory);
     
             // 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
             // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
             // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
             registerBeanPostProcessors(beanFactory);
     
             // 初始化当前 ApplicationContext 的 MessageSource,国际化这里就不展开说了,不然没完没了了
             initMessageSource();
     
             // 初始化当前 ApplicationContext 的事件广播器,这里也不展开了
             initApplicationEventMulticaster();
     
             // 从方法名就可以知道,典型的模板方法(钩子方法),
             // 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
             onRefresh();
     
             // 注册事件监听器,监听器需要实现 ApplicationListener 接口。这也不是我们的重点,过
             registerListeners();
     
             // 重点,重点,重点
             // 初始化所有的 singleton beans
             //(lazy-init 的除外)
             finishBeanFactoryInitialization(beanFactory);
     
             // 最后,广播事件,ApplicationContext 初始化完成
             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.
             // 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
             destroyBeans();
     
             // Reset 'active' flag.
             cancelRefresh(ex);
     
             // 把异常往外抛
             throw ex;
          }
     
          finally {
             // Reset common introspection caches in Spring's core, since we
             // might not ever need metadata for singleton beans anymore...
             resetCommonCaches();
          }
       }

     

    refresh 解析

      创建容器前的准备工作

      prepareRefresh()

           创建Bean 容器,加载并注册Bean

      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        refreshBeanFactory();

          //初始化一个 DefaultListableBeanFactory

          DefaultListableBeanFactory beanFactory = createBeanFactory();

          //加载 Bean 到 BeanFactory 中

          loadBeanDefinitions(beanFactory);

             //给这个 BeanFactory 实例化一个 XmlBeanDefinitionReader

                XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

             // 初始化 BeanDefinitionReader,其实这个是提供给子类覆写的,

             initBeanDefinitionReader(beanDefinitionReader);

             loadBeanDefinitions(beanDefinitionReader);

               loadBeanDefinitions(new EncodedResource(resource))

                doLoadBeanDefinitions(inputSource, encodedResource.getResource())

                  registerBeanDefinitions(doc, resource)

                    //配置文件转换为 DOM 树

                    registerBeanDefinitions(doc, createReaderContext(resource));

                      doRegisterBeanDefinitions(root)

                        // 解析Bean标签

                        parseBeanDefinitions(root, this.delegate);

                           parseDefaultElement(ele, delegate); 

                             // 解析 Bean 标签

                             processBeanDefinition(ele, delegate);  

                                // 注册bean

                                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());                    

                           delegate.parseCustomElement(ele);

           // 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean

      prepareBeanFactory(beanFactory);

      // 提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化

      postProcessBeanFactory(beanFactory);

      // 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法

      invokeBeanFactoryPostProcessors(beanFactory);

      // 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别

      registerBeanPostProcessors(beanFactory);

      // 初始化当前 ApplicationContext 的 MessageSource

      initMessageSource();

      // 初始化当前 ApplicationContext 的事件广播器

      initApplicationEventMulticaster();

      //初始化一些特殊的 Bean(在初始化 singleton beans 之前)

      onRefresh(); 

      // 注册事件监听器,监听器需要实现 ApplicationListener 接口   

      registerListeners();

      // 初始化所有的 singleton beans

      finishBeanFactoryInitialization(beanFactory);

    总结

      1、找准入口 ,使用ClassPathXmlApplicationContext加载配置文件,用于加载classPath下的配置文件

      2、解析传入的路径中的占位符,集合org.springframework.core.env.AbstractPropertyResolverorg.springframework.util.PropertyPlaceholderHelper

      3、刷新上下文

    ​     1、prepareRefresh() : 准备刷新,设置一些活动标志,比如开始时间,当前的状态

    ​     2、ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory():从spring的配置文件中加载bean,封装成BeanDefinition,注册到注册表中,创建beanFactory

    ​     3、prepareBeanFactory(beanFactory); :准备BeanFactory,设置累加载器,添加后置处理器,SPL表达式解析器,向ioc容器中注入一些组件

      ​ 4、postProcessBeanFactory(beanFactory); : 允许子类做一些处理操作

      ​ 5、invokeBeanFactoryPostProcessors(beanFactory); :调用BeanFactoryProcessor,先是调用BeanDefitionRegistoyPostProcessor,之后调用BeanFactoryProcessor

      ​ 6、registerBeanPostProcessors(beanFactory); : 将配置文件中读取的Bean的后置处理器注册到容器中

    ​   7、initMessageSource(); :初始化消息源,用于国际化

    ​   8、initApplicationEventMulticaster() : 初始化事件广播器,判断容器中是否已经注册了该组件,如果没有该组件,那么使用默认的

      ​ 9、onRefresh(); :子类初始化一些特殊的bean

    ​   10、registerListeners(); :注册事件监听器

      ​ 11、finishBeanFactoryInitialization(beanFactory) :完成初始化,初始化非懒加载的bean

      ​ 12、finishRefresh(); :完成刷新,最后一步,初始化生命周期处理器,派发事件

    -------------------------------------------------------------------------------------------------------------------------

     参考:

    【1】https://www.jianshu.com/p/33c471aff85c

    【2】https://www.cnblogs.com/xrq730/p/6285358.html

     

  • 相关阅读:
    Spring Boot2 系列教程(二十)Spring Boot 整合JdbcTemplate 多数据源
    Spring Boot 如何给微信公众号返回消息
    Spring Boot2 系列教程(十九)Spring Boot 整合 JdbcTemplate
    Spring Boot2 系列教程(十八)Spring Boot 中自定义 SpringMVC 配置
    Spring Boot 开发微信公众号后台
    Spring Boot2 系列教程(十七)SpringBoot 整合 Swagger2
    Spring Boot2 系列教程(十六)定时任务的两种实现方式
    Spring Boot2 系列教程(十五)定义系统启动任务的两种方式
    Spring Boot2 系列教程(十四)CORS 解决跨域问题
    JavaScript二维数组
  • 原文地址:https://www.cnblogs.com/Jomini/p/13753711.html
Copyright © 2011-2022 走看看