几个重要的事件回调机制

  1. 配置在META-INF/spring.factroies
    • ApplicationContextInitializer
    • SpringApplicationRunListener
  2. 只需要放在ioc容器中
    • ApplicationRunner
    • CommandLineRunner

Spring Boot启动流程:

1、创建SpringApplication对象

2、运行run方法

  1. public ConfigurableApplicationContext run(String... args) {
  2. StopWatch stopWatch = new StopWatch();
  3. stopWatch.start();
  4. ConfigurableApplicationContext context = null;
  5. Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
  6. configureHeadlessProperty();
  7. // 获取SpringApplicationRunListeners;从类路径下META-INF/spring.factories
  8. SpringApplicationRunListeners listeners = getRunListeners(args);
  9. // 回调所有的获取SpringApplicationRunListener.starting()方法
  10. listeners.starting();
  11. try {
  12. // 封装命令行参数
  13. ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
  14. // 准备环境
  15. ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
  16. configureIgnoreBeanInfo(environment);
  17. // 创建环境完成后回调SpringApplicationRunListener.environmentPrepared();表示环境准备完成
  18. Banner printedBanner = printBanner(environment);
  19. // 创建ApplicationConetxt;决定创建web的ioc还是普通的ioc
  20. context = createApplicationContext();
  21. // 加载环境
  22. exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
  23. new Class[] { ConfigurableApplicationContext.class }, context);
  24. // 准备上下文环境;将environment保存到ioc中,并且applyInitializers();
  25. // applyInitializers():回调之前保存的所有的ApplicaionContextInitalizer的initialize方法
  26. // 回调所有的SpringApplicationRunLIstener的ContextPrepared();
  27. prepareContext(context, environment, listeners, applicationArguments, printedBanner);
  28. // preparedContext运行完成以后回调所有的SpringApplicationRunListener的contextLoaded();
  29. // 刷新容器,ioc容器初始化(如果是web应用还会创建嵌入式的Tomcat);
  30. // 扫描,创建,加载所有组件的地方;(配置类,组件,自动配置)
  31. refreshContext(context);
  32. // 从ioc容器中获取所有的ApplicationRunner和CommadLineRunner进行回调
  33. // ApplicationRunner先回调,CommandLineRunner再回调
  34. afterRefresh(context, applicationArguments);
  35. stopWatch.stop();
  36. if (this.logStartupInfo) {
  37. new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
  38. }
  39. listeners.started(context);
  40. callRunners(context, applicationArguments);
  41. }
  42. catch (Throwable ex) {
  43. handleRunFailure(context, ex, exceptionReporters, listeners);
  44. throw new IllegalStateException(ex);
  45. }
  46. try {
  47. // 启动监听器
  48. listeners.running(context);
  49. }
  50. catch (Throwable ex) {
  51. handleRunFailure(context, ex, exceptionReporters, null);
  52. throw new IllegalStateException(ex);
  53. }
  54. // 整个SpringBoot应用启动完成以后返回启动的ioc容器
  55. return context;
  56. }

3、事件监听机制

配置在META-INF/spring.factories

ApplicationContextInitializer

  1. public class HelloApplicationContextInitializer implements ApplicationContextInitializer {
  2. @Override
  3. public void initialize(ConfigurableApplicationContext applicationContext) {
  4. System.out.println("HelloApplicationContextInitializer.initialize:" + applicationContext);
  5. }
  6. }

SpringApplicationRunListener

  1. public class HelloSpringApplicationRunListener implements SpringApplicationRunListener {
  2. public HelloSpringApplicationRunListener(SpringApplication application, String[] args) {
  3. }
  4. @Override
  5. public void starting() {
  6. System.out.println("HelloSpringApplicationRunListener.starting");
  7. }
  8. @Override
  9. public void environmentPrepared(ConfigurableEnvironment environment) {
  10. System.out.println("HelloSpringApplicationRunListener.environmentPrepared");
  11. }
  12. @Override
  13. public void contextPrepared(ConfigurableApplicationContext context) {
  14. System.out.println("HelloSpringApplicationRunListener.contextPrepared");
  15. }
  16. @Override
  17. public void contextLoaded(ConfigurableApplicationContext context) {
  18. }
  19. @Override
  20. public void started(ConfigurableApplicationContext context) {
  21. System.out.println("HelloSpringApplicationRunListener.started");
  22. }
  23. @Override
  24. public void running(ConfigurableApplicationContext context) {
  25. System.out.println("HelloSpringApplicationRunListener.running");
  26. }
  27. @Override
  28. public void failed(ConfigurableApplicationContext context, Throwable exception) {
  29. System.out.println("HelloSpringApplicationRunListener.failed");
  30. }
  31. }

配置(META-INF/spring.factories)

org.springframework.context.ApplicationContextInitializer=\
  com.zh.springboot.listener.HelloApplicationContextInitializer

org.springframework.boot.SpringApplicationRunListener=\
  com.zh.springboot.listener.HelloSpringApplicationRunListener

只需要放在IOC容器中

ApplicationRunner

@Component
public class HelloApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("HelloApplicationRunner.run");
    }
}

CommandLineRunner

@Component
public class HelloCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("HelloCommandLineRunner.run");
    }
}