SpringBoot启动流程(4) | 七日打卡

796 阅读2分钟

前言

之前有说过整个项目中已经加载了Bean,接下来就是最后项目收尾过程了。当然除了是收尾的部分还要进行一个完美的总结。

代码步骤讲解

代码部分

这里挑选了部分代码

afterRefresh(context, applicationArguments);

listeners.started(context);
callRunners(context, applicationArguments);

listeners.running(context);

流程讲解

  1. afterRefresh(context, applicationArguments);
    在上下文刷新后调用(这里是个空实现)。
  2. listeners.started(context);
    绑定TomcatMetrics
  3. callRunners(context, applicationArguments);
    这里开始调用ApplicationRunner以及CommandLineRunner
  4. listeners.running(context); 将在平台MBeanServer上公开SpringApplicationAdminMXBean

最后的步骤都是围绕着整个项目的安全考虑的,开放追踪以及MBean等。不加入其他组件,一个简易的SpringBoot就启动完成了,当然里面的东西还是很多的,要知道Bean什么时候加载进入整个容器中,以及个别Bean后处理器的作用等等。

总结

  1. 首先创建SpringApplication对象实例。

    1. 根据classpath里面是否存在某个特征类(ConfigurableWebApplicationContext)来决定创建一个web应用的ApplicationContext还是Standalone应用的ApplicationContext
    2. SpringFactoriesLoaderclasspath中查找并加载所有可用的ApplicationContextInitializer
    3. SpringFactoriesLoaderclasspath中查找并加载所有可用的ApplicationListener
    4. 推断并设置main方法的定义类
  2. 执行run方法。遍历所有通过SpringFactoriesLoader查找并加载的SpringApplicationRunListener,并调用其started()方法。

  3. 创建并配置当前SpringBoot应用将要使用的Environment(包括配置要使用的PropertySource以及Profile)。

  4. 遍历调用所有的SpringApplicationRunListenerenvironmentPrepared()的方法。说明当前的environment准备好。

  5. 如果showBanner属性设置为true,则打印banner

  6. 根据用户是否明确设置了applicationContextClass类型以及初始化阶段的推断结果,为SpringBoot创建什么类型的ApplicationConext,根据条件决定是否添加shutdownHook,决定是否使用自定义的BeanNameGenerator,决定是否使用自定的ResourceLoader。最重要的是将之前准备好的Environment设置给创建好的ApplicationContext使用。

  7. ApplicationContext创建好之后,借助SpringFactoriesLoader查找所有可用的ApplicationContextInitializer,然后调用其initialize方法进一步对已创建好的ApplicationContext进一步处理。

  8. 遍历调用所有的SpringApplicationRunListenercontextPrepared()方法ApplicationContext准备好。

  9. 核心的步骤:之前通过@EnableAutoConfiguration获取的所有配置以及其他形式的IOC容器配置加载到已经准备完毕的ApplicationContext中。

  10. 遍历所有的SpringApplicationRunListenercontextLoaded()方法,告知所有的 SpringApplicationRunListenerApplicationContext装填完毕

  11. 调用ApplicationContext的refresh()方法,完成IOC容器可用的最后一道工序。

  12. 查找当前的ApplicationContext中是否注册有CommandLineRunner,如果有则进行遍历执行。

  13. 遍历执行SpringApplicationRunListenerfinished()方法,告知他们完成。