SpringBoot如何Run起来的 - 图2

SpringBoot启动过程图解 - Java天堂

实例化SpringApplication

  1. public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
  2. this.resourceLoader = resourceLoader;
  3. Assert.notNull(primarySources, "PrimarySources must not be null");
  4. this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
  5. this.webApplicationType = deduceWebApplicationType();
  6. // 使用SpringFactoriesLoader.loadFactoryNames(SPI)来获取设置ApplicationContextInitializer类名
  7. // 使用BeanUtils.instantiateClass 来构造设置ApplicationContextInitializer对象
  8. // 设置ApplicationContextInitializer 到 SpringApplication.initializers 属性中
  9. setInitializers((Collection) getSpringFactoriesInstances(
  10. ApplicationContextInitializer.class));
  11. //用同样的方式加载 ApplicationListener
  12. setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
  13. // 设置main方法所在的类。
  14. this.mainApplicationClass = deduceMainApplicationClass();
  15. }

加载ApplicationContextInitializer

  • SPI获取ApplicationContextInitializer
    • image.png
  • 设置ApplicationContextInitializer到SpringApplication

    加载ApplicationListener

  • 用同样的方式加载 ApplicationListener

    • image.png

      执行run方法

  • SpringApplicationRunListeners

    • image.png

      public ConfigurableApplicationContext run(String… args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Collection exceptionReporters = new ArrayList<>(); configureHeadlessProperty();

      1. //获取 SpringApplicationRunListener ,扩展点,用得少

      SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting(); try {

      1. ApplicationArguments applicationArguments = new DefaultApplicationArguments(
      2. args);
      3. //创建Environment,web和app创建类型不一样
      4. ConfigurableEnvironment environment = prepareEnvironment(listeners,
      5. applicationArguments);
      6. configureIgnoreBeanInfo(environment);
      7. Banner printedBanner = printBanner(environment);
      8. //创建ApplicationContext,
      9. //web=AnnotationConfigEmbeddedWebApplicationContext
      10. //app=AnnotationConfigApplicationContext
      11. context = createApplicationContext();
      12. exceptionReporters = getSpringFactoriesInstances(
      13. SpringBootExceptionReporter.class,
      14. new Class[] { ConfigurableApplicationContext.class }, context);
      15. //执行ApplicationContextInitializer initialize() 方法
      16. //执行SpringApplicationRunListener.contextPrepared()
      17. //注入ApplicationArguments对象
      18. //加载source到context中
      19. prepareContext(context, environment, listeners, applicationArguments,
      20. printedBanner);
      21. //调用context.refresh(),这就转到spring内部管理实例化bean等操作
      22. refreshContext(context);
      23. //回调ApplicationRunner、ConmmandLineRunner(开机自启动)
      24. afterRefresh(context, applicationArguments);
      25. stopWatch.stop();
      26. if (this.logStartupInfo) {
      27. new StartupInfoLogger(this.mainApplicationClass)
      28. .logStarted(getApplicationLog(), stopWatch);
      29. }
      30. listeners.started(context);
      31. callRunners(context, applicationArguments);

      } catch (Throwable ex) {

      1. handleRunFailure(context, ex, exceptionReporters, listeners);
      2. throw new IllegalStateException(ex);

      }

      try {

      1. listeners.running(context);

      } catch (Throwable ex) {

      1. handleRunFailure(context, ex, exceptionReporters, null);
      2. throw new IllegalStateException(ex);

      } return context; }

getRunListeners(args);

【事件】listeners.starting();

prepareEnvironment

创建Environment

【事件】listeners.environmentPrepared(bootstrapContext, environment);

ConfigFileApplicationListener监听

ConfigFileApplicationListener#onApplicationEnvironmentPreparedEvent
执行EnvironmentPostProcessor#postProcessEnvironment
image.png

获取placeholdersResolver、resourceLoader、propertySourceLoaders

image.png

解析配置文件

image.png
默认配置文件位置:
image.png

spring cloud加载配置文件:BootstrapApplicationListener

SpringCloud

绑定spring.main到SpringApplication

image.png
image.png

createApplicationContext();

prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);

applyInitializers(context);

DelegatingApplicationContextInitializer

image.png

  • ConfigDataEnvironmentPostProcessor负责读取application.properties,加载到Environment。

    【事件】listeners.contextPrepared(context);

    加载BeanDefinition

    image.png

    【事件】listeners.contextLoaded(context);

【applicationContext.refresh()】refreshContext(context);

【事件】listeners.started(context);

【ApplicationRunner】callRunners(context, applicationArguments);

【事件】listeners.running(context);