• Spring源码阅读-ClassPathXmlApplicationContext


    第一步:new一个ClassPathXmlApplicationContext对象

    ClassPathXmlApplicationContext xmlContext = new ClassPathXmlApplicationContext("mylearn.xml");

    第二步:调用构造方法

    public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
       this(new String[] {configLocation}, true, null);
    }
    
    public ClassPathXmlApplicationContext(
          String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
          throws BeansException {
    
       super(parent);
       //设置上下文的配置路径
       setConfigLocations(configLocations);
       if (refresh) {
          //刷新上下文
          refresh();
       }
    }
    public void setConfigLocations(@Nullable String... locations) {
       if (locations != null) {
          Assert.noNullElements(locations, "Config locations must not be null");
          this.configLocations = new String[locations.length];
          for (int i = 0; i < locations.length; i++) {
             this.configLocations[i] = resolvePath(locations[i]).trim();
          }
       }
       else {
          this.configLocations = null;
       }
    }
    @Override
    public void refresh() throws BeansException, IllegalStateException {
       synchronized (this.startupShutdownMonitor) {
          StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
    
          // Prepare this context for refreshing.
          prepareRefresh();
    
          // Tell the subclass to refresh the internal bean factory.
          ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
          // Prepare the bean factory for use in this context.
          prepareBeanFactory(beanFactory);
    
          try {
             // Allows post-processing of the bean factory in context subclasses.
             postProcessBeanFactory(beanFactory);
    
             StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
             // Invoke factory processors registered as beans in the context.
             invokeBeanFactoryPostProcessors(beanFactory);
    
             // Register bean processors that intercept bean creation.
             registerBeanPostProcessors(beanFactory);
             beanPostProcess.end();
    
             // Initialize message source for this context.
             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.
             finishBeanFactoryInitialization(beanFactory);
    
             // Last step: publish corresponding event.
             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();
             contextRefresh.end();
          }
       }
    }

    第三步:调用抽象父类AbstractXmlApplicationContext

    public AbstractXmlApplicationContext(@Nullable ApplicationContext parent) {
       super(parent);
    }

    第四步:调用抽象父类AbstractRefreshableConfigApplicationContext

    public AbstractRefreshableConfigApplicationContext(@Nullable ApplicationContext parent) {
       super(parent);
    }

    第五步:调用抽象父类AbstractRefreshableApplicationContext

    public AbstractRefreshableConfigApplicationContext(@Nullable ApplicationContext parent) {
       super(parent);
    }

    第六步:调用抽象父类AbstractApplicationContext

    public AbstractApplicationContext(@Nullable ApplicationContext parent) {
       this();
       setParent(parent);
    }
    public AbstractApplicationContext() {
       this.resourcePatternResolver = getResourcePatternResolver();
    }

    获取接口解析器 ResourcePatternResolver

    protected ResourcePatternResolver getResourcePatternResolver() {
       return new PathMatchingResourcePatternResolver(this);
    }

    第七步:设置应用上下文接口ApplicationContext

    @Override
    public void setParent(@Nullable ApplicationContext parent) {
       this.parent = parent;
       if (parent != null) {
          Environment parentEnvironment = parent.getEnvironment();
          if (parentEnvironment instanceof ConfigurableEnvironment) {
             getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
          }
       }
    }

  • 相关阅读:
    【算法leetcode】面试题 04.03. 特定深度节点链表(多语言实现)
    微服务生态系统:使用Spring Cloud构建分布式系统
    云呐-人工智能设备运维是干什么的?自动化设备运维
    Java集合面试题
    值类型与引用类型的区别,以及string类型的解释
    【每日一题】中缀表达式计算详解(基本计算器 II,表达式计算4)
    HTTP请求行详解
    TortoiseGit间接处理linux目录下的仓库,用到window映射linux目录方案
    2022/8/4 树上差分+线段树
    试试这2个流动图片制作方法让你的图片动起来吧
  • 原文地址:https://blog.csdn.net/weixin_39059334/article/details/134321887