【SpringBoot2】启动流程源码简析

1. Spring Boot启动类的@SpringBootApplication注解

@SpringBootApplication 注解是一个组合注解,主要有以下三个:

  • @SpringBootConfiguration:表示一个类提供了Spring Boot的配置。

  • @ComponentScan:定义 Spring 扫描的包,它默认会扫描标注为Spring Bean的类,并实例化这些组件到 SpringIOC 容器中。

  • @EnableAutoConfigration:核心注解——自动配置包,它会获取主程序类所在的包路径,并将包路径(包括子包)下的所有组件注册到 SpringIOC 容器中。

2. SpringApplication.run(DemoApplication.class, args)

直接看源码吧

// 0. 调用 SpringApplication.run(...)静态方法后,它会new一个SpringApplication去调用真正的run方法。
public ConfigurableApplicationContext run(String... args) {
   StopWatch stopWatch = new StopWatch();
   stopWatch.start();
   ConfigurableApplicationContext context = null;
   Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
   configureHeadlessProperty();
// 1. 初始化监听器并启动,Spring容器的启动都是从监听器开始的,就像Spring4需要配置xml的时候也是首先在web.xml中配置Spring的监听器
// 2. 然后这里会发布ApplicationStartedEvent事件。
   SpringApplicationRunListeners listeners = getRunListeners(args);
   listeners.starting();
   try {
// 3. 接着进入一个大try-catch,平时开发时遇到Spring Boot启动失败却没有打印出错误信息,我就会把断点打在这里dubug。
// 4. Try里面第一步时装配参数和环境,选择对的profile
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(
            args);
// 5. 装配完环境后会触发ApplicationEnvironmentPreparedEvent事件
      ConfigurableEnvironment environment = prepareEnvironment(listeners,
            applicationArguments);
      configureIgnoreBeanInfo(environment);
// 6. 接着就会打印Banner(外国人的开源项目都喜欢这样,redis也会打印他的图标。)
      Banner printedBanner = printBanner(environment);
// 7. 然后会根据是否web环境创建Spring的应用上下文
      context = createApplicationContext();
      exceptionReporters = getSpringFactoriesInstances(
            SpringBootExceptionReporter.class,
            new Class[] { ConfigurableApplicationContext.class }, context);
// 8. 创建好后就装配应用上下文
      prepareContext(context, environment, listeners, applicationArguments,
            printedBanner);
// 9. 接着刷新上下文,(刷新结束后调用afterRefresh方法,这是个空实现,猜测是个钩子方法)
      refreshContext(context);
      afterRefresh(context, applicationArguments);
      stopWatch.stop();
      if (this.logStartupInfo) {
         new StartupInfoLogger(this.mainApplicationClass)
               .logStarted(getApplicationLog(), stopWatch);
      }
// 10. 刷新结束后会发布ApplicationReadyEvent事件
      listeners.started(context);
// 11. 然后会调用自定的Runner。(这些Runner 用在 SpringApplication启动后运行一些特殊代码)
      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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值