1 启动流程

  • SpringBoot启动配置原理 - 图1创建SpringApplication对象。
  1. public class SpringApplication {
  2. //SpringBoot应用启动,调用此方法
  3. public static ConfigurableApplicationContext run(Object source, String... args) {
  4. return run(new Object[] { source }, args);
  5. }
  6. public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
  7. return new SpringApplication(sources).run(args);
  8. }
  9. public SpringApplication(Object... sources) {
  10. //初始化
  11. initialize(sources);
  12. }
  13. private void initialize(Object[] sources) {
  14. //保存主配置类
  15. if (sources != null && sources.length > 0) {
  16. this.sources.addAll(Arrays.asList(sources));
  17. }
  18. //当前应用是否是web应用
  19. this.webEnvironment = deduceWebEnvironment();
  20. //从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer,然后保存起来
  21. setInitializers((Collection) getSpringFactoriesInstances(
  22. ApplicationContextInitializer.class));
  23. //从类路径下找到META-INF/spring.factories配置的所有ApplicationListener,然后保存起来
  24. setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
  25. //从多个配置类中找到有main方法的主配置类
  26. this.mainApplicationClass = deduceMainApplicationClass();
  27. }
  28. //其他略
  29. }

ApplicationContextInitializer.png
ApplicationListener.png

  • SpringBoot启动配置原理 - 图4通过SpringApplication对象调用run()方法。
  1. public class SpringApplication {
  2. /**
  3. * Run the Spring application, creating and refreshing a new
  4. * {@link ApplicationContext}.
  5. * @param args the application arguments (usually passed from a Java main method)
  6. * @return a running {@link ApplicationContext}
  7. */
  8. public ConfigurableApplicationContext run(String... args) {
  9. StopWatch stopWatch = new StopWatch();
  10. stopWatch.start();
  11. ConfigurableApplicationContext context = null;
  12. FailureAnalyzers analyzers = null;
  13. configureHeadlessProperty();
  14. //获取SpringApplicationRunListeners,从类路径下的找到META-INF/spring.factories配置的所有SpringApplicationRunListener
  15. SpringApplicationRunListeners listeners = getRunListeners(args);
  16. //回调所有SpringApplicationRunListener的starting方法
  17. listeners.starting();
  18. try {
  19. //封装命令行参数
  20. ApplicationArguments applicationArguments = new DefaultApplicationArguments(
  21. args);
  22. /*
  23. * 准备环境:
  24. * - 创建环境完成后回调所有SpringApplicationRunListener的environmentPrepared方法;表示环境准备完成
  25. */
  26. ConfigurableEnvironment environment = prepareEnvironment(listeners,
  27. applicationArguments);
  28. //打印Banner
  29. Banner printedBanner = printBanner(environment);
  30. //创建ApplicationContext。决定创建Web的IOC容器还是普通的IOC容器
  31. context = createApplicationContext();
  32. analyzers = new FailureAnalyzers(context);
  33. //准备上下文环境,将environment保存到IOC容器中,applyInitializers(context);回到之前保存的所有的ApplicationContextInitializer的initialize()方法,回调listeners.contextPrepared(context);
  34. prepareContext(context, environment, listeners, applicationArguments,
  35. printedBanner);
  36. //prepareContext完成后,回调listeners.contextLoaded(context);
  37. //刷新容器。IOC容器初始化
  38. refreshContext(context);
  39. //从IOC容器中获取所有的ApplicationRunner和CommandLineRunner进行回调
  40. afterRefresh(context, applicationArguments);
  41. //所有的SpringApplicationRunListener回调finished方法
  42. listeners.finished(context, null);
  43. stopWatch.stop();
  44. if (this.logStartupInfo) {
  45. new StartupInfoLogger(this.mainApplicationClass)
  46. .logStarted(getApplicationLog(), stopWatch);
  47. }
  48. //整个SpringBoot启动完成以后,返回启动的IOC容器
  49. return context;
  50. }
  51. catch (Throwable ex) {
  52. handleRunFailure(context, listeners, analyzers, ex);
  53. throw new IllegalStateException(ex);
  54. }
  55. }
  56. }

2 总结事件回调机制

  • 需要配置在META-INF/spring.factories的事件是:
    • ApplicationContextInitializer。
    • ApplicationListener。
  • 不需要配置在META-INF/spring.factories,只需要加入到IOC容器的事件是:
    • ApplicationRunner。
    • CommandLineRunner。