面试的常见一招:请谈谈XXX的实现原理。我就觉得,你要是知道自己都去写框架了。。。玩笑,大神还是一堆一堆的,都是要供起来的
一、SpringBoot的启动原理
- 当我们启动SpringBoot程序的时候都是去运行SpringBoot成体提供的主类的main方法;
- 当main方法运行起来的时候就调用SpringApplication.run方法,两个参数。一个是当前类的字节码对象,另一个是main方法的命令行参数;
- 这个run方法里面创建了一个SpringApplication对象,参数就是装有主类字节码对象的Object数组,创建对象就是调用了该对象中的一个initialize方法,这个方法保存了当前程序的主类,然后判断当前应用是不是一个web应用,然后保存类路径下找到 META‐INF/spring.factories 配置的所有ApplicationContextInitializer和ApplicationListener,最后从程序的调用堆栈中找到main方法所在的类并保存;然后再调用SpringApplication对象的run方法;
- 这个run方法首先从类路径下 META‐INF/spring.factories 中找到所有的SpringApplicationRunListeners,并启动这些监听器,接着配置运行的相关参数,在配置完成后,就会回调所有监听器的environmentPrepared方法,即环境准备完成;接着如果当前环境不是一个web环境,那就把当前环境转换成一个web环境;然后就打印控制台上的Spring图标;接着,创建IoC容器:AnnotationConfigEmbeddedWebApplicationContext,然后把前面准备的运行参数ConfigurableEnvironment设置到容器中,然后调用前面保存的所有ApplicationContextInitializer的initialize方法,并把容器传递进去,然后回调所有监听器的contextPrepared方法,设置各种参数,比如命令行参数等,就会调用所有监听器的contextLoaded方法;接着就回去执行refreshContext方法,这个方法中就会去扫描项目中的各种配置类,组件等等进行Bean的装载;在完成组件的装配之后,就会从IoC容器中获取所有的ApplicationRunner和CommandLineRunner进行回调,最后调用所有监听器的finished方法并返回容器对象;