2.Springboot2启动过程源码分析-SpringApplication#run

系列文章目录

1.Springboot2启动过程源码分析-SpringApplication初始化

2.Springboot2启动过程源码分析-SpringApplication#run

3.Springboot2启动过程源码分析-prepareContext方法

4.Springboot2启动过程源码分析-refresh方法

5.Springboot2启动过程源码分析-Bean的实例化

6.Springboot2启动过程源码分析-总结


 

文章目录


前言

上一节对SpringApplication实例化的过程进行了分析,在实例化后就会调用SpringApplication的run方法

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
   return new SpringApplication(primarySources).run(args);
}

 


本节来看下SpringApplication的run方法都做了什么

 

SpringApplication#run

以下为run方法的源码及添加的注释

public ConfigurableApplicationContext run(String... args) {
   StopWatch stopWatch = new StopWatch();
   stopWatch.start();
   ConfigurableApplicationContext context = null;
   Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
   configureHeadlessProperty();
   //1.获取SpringApplicationRunListeners对象
   SpringApplicationRunListeners listeners = getRunListeners(args);
   listeners.starting();
   try {
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
      //2.构造上下文环境对象StandardServletEnvironment
      //在prepareEnvironment中会获取到Profile,系统配置application.properties的信息
      ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
      configureIgnoreBeanInfo(environment);
      Banner printedBanner = printBanner(environment);
      //3.初始化上下文,实例化AnnotationConfigServletWebServerApplicationContext对象
      context = createApplicationContext();
      exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
            new Class[] { ConfigurableApplicationContext.class }, context);
      //4.刷新上下文前的准备阶段
      prepareContext(context, environment, listeners, applicationArguments, printedBanner);
      //5.刷新上下文,包含bean的创建
      refreshContext(context);
      //6.刷新上下文后的阶段
      //目前afterRefresh方法体是空的,可能是预留的方法或者是给大家自行扩展用的
      afterRefresh(context, applicationArguments);
      stopWatch.stop();
      if (this.logStartupInfo) {
         new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
      }
      //7. 启动监听器
      listeners.started(context);
      callRunners(context, applicationArguments);
   }
   catch (Throwable ex) {
      handleRunFailure(context, ex, exceptionReporters, listeners);
      throw new IllegalStateException(ex);
   }

   try {
      listeners.running(context);
   }
   catch (Throwable ex) {
      handleRunFailure(context, ex, exceptionReporters, null);
      throw new IllegalStateException(ex);
   }
   return context;
}

run方法主要进行的7个步骤:

1. getRunListeners -> 获取监听器

    new SpringApplicationRunListeners的实例

2. prepareEnvironment -> 构造上下文的环境(包括加载指定的profile,加载对应的配置文件)

3. createApplicationContext -> 初始化上下文

    createApplicationContext方法内部会通过BeanUtils的instantiateClass反射获取AnnotationConfigServletWebServerApplicationContext实例。在调用AnnotationConfigServletWebServerApplicationContext默认的构造函数时,会实例化两个重要的类:

public AnnotationConfigServletWebServerApplicationContext() {
   this.reader = new AnnotatedBeanDefinitionReader(this);
   this.scanner = new ClassPathBeanDefinitionScanner(this);
}

AnnotatedBeanDefinitionReader: 注解Bean读取器,用于读取和解析bean定义

ClassPathBeanDefinitionScanner: 扫描basePackages定路径下@Component的类极其派生类

4. prepareContext -> 刷新上下文前的准备阶段

    这个方法后面会专门有一节进行详细的介绍

5.refreshContext -> 刷新上下文,包含bean的创建 ,webServer创建(如内嵌的tomcat创建启动)

   调用AbstractApplicationContext#refresh,也会专门有一节进行介绍

6. afterRefresh -> 刷新上下文后的阶段

    方法体是空的

7. listeners.started -> 启动监听器

    发布ApplicationStartedEvent事件监听器

 

总结

以上就是对SpringApplication的run方法主要流程的分析。

这里每一块源码拿出来都可以拓展出很多内容,也应用了很多经典的设计模式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhao_rock_2016

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值