SpringBoot启动流程与源码

  一 main方法作为程序的入口,执行SpringApplication.run(),传入参数是启动类的class对象@SpringBootApplication注解

二 run中首先new SpringApplication对象,然后调用该对象的run方法,返回是一个ConfigurableApplicationContext对象。

三 这里我们先看new SpringApplication的时候会进行什么操作,run方法随后在看,这段代码中的每一步依次来说:

  1.使用了Assert.notNull来判断空值是一个良好的习惯,Assert类来自core的org.springframework.util包下,该包提供了很多工具类,之后会单独有一篇介绍  spring提供给我们好用的工具类的文章。

  2.其中会deduceFromClasspath(deduce意为“推断”)应用类型是servlet还是reactive

classPath中这三个最少有一个

并且这两个全都有才是一个web应用

  3.getSpringFactoriesInstance(ApplicationContextInitiliazer.class)方法从spring-boot包下的"META-INF/spring.factories"路径加载ClassLoader

该文件:

这种方式更容易看懂共有八个接口分别对应多个实现类:

其中只取key为ApplicationContextInitializer的value返回,该value是个List<String>,是实现了ApplicationContextInitializer接口的实现类名称,以“,”分隔

然后将这些类进行加载,这些类指的是:

之后同样的方式加载ApplicationListener接口的实现类:

 

 4.判定主程序是哪个类

 通过遍历栈信息,找到调用main方法的类型,将其加载,赋值给变量mainApplicationClass

 四 SpringApplication的run方法

其中重要的逻辑都用黄色框圈了出来:

  1.加载所有的监听器,和上述一样,加载指定好的类都是根据spring.factories中的对应的监听器,加载EventPublishingRunListener,之后调用该类的starting:

 

之后调用该类的starting方法,对之前加载的所有ApplicationListener根据事件类型进行广播事件(multicastEvent):

  2.准备容器环境,会依据之前推断(deduce)的应用类型返回对应的环境对象:   

 

  之后由监听器执行enviromentPrepared方法,其中需要注意的是会有一个监听器叫:ConfigFileApplicationListener,该接口的实现类会实际加载yml或.properties的配置文件:

  

  

  

随后在执行ConfigFileApplicationLitener的postProcessEnviroment方法时,会加载factories的PropertySourceLoader对应的实现类:

来加载yml或.properties中的配置,至此,容器环境配置完成。

  3.创建容器上下文createApplicationContext(),也是依据之前的应用类型推断结果:

  

  之后准备容器上下文:

  

  首先将创建的context中的enviroment全部替换为springApplication中刚刚创建的enviroment,然后向context中注册beanfactory:

  

  然后用当前context作为参数,调用springApplication中所有的intilizer实现类执行,intilize方法,其中重点关注COnfigurationWaringsApplicationContextInitializer类的该方法:

  

  所有的listener执行contetxPrepared方法,之后向beanfacotry中注册两个参数,之后是load方法:

      创建了一个beanDefinitionLoader对象,该对象最主要支持了xml加载和annotated加载方式,加载所有source中的对象,这里只有一个主类,被@Component注解(注解继承),将其注入到beanfactory中的beanDefinitionMap中

  

  在refreshContext中会加载所有的bean到beanFactory中:

    

    

  至此,就将所有的bean由容器来管理。

posted @ 2019-05-04 19:02  有一个小梦想  阅读(17185)  评论(0编辑  收藏  举报