文章目录
核心启动代码分析
我们最常见的SpringBoot启动代码:
java
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
这行代码背后隐藏着复杂的启动逻辑,整个过程可以分为两个核心阶段。
第一阶段:SpringApplication实例创建
当调用SpringApplication.run()
时,首先会创建SpringApplication实例。这个过程中SpringBoot做了几件关键的事情:
-
应用类型推断 :SpringBoot会检查classpath中的关键类来判断应用类型。如果发现
DispatcherServlet
类,判定为servlet类型。这个判断决定了后续创建什么类型的ApplicationContext。 -
加载初始化器和监听器 :从META-INF/spring.factories文件中读取ApplicationContextInitializer 和ApplicationListener的实现类。这些组件会在启动过程的特定阶段发挥作用。
-
确定主启动类:通过分析当前线程堆栈,找到包含main方法的类,通常就是我们标注了@SpringBootApplication的启动类。
第二阶段:run方法执行过程
SpringApplication实例创建完成后,开始执行run方法,这是整个启动流程的精华部分:
环境准备
创建ConfigurableEnvironment对象,这是SpringBoot配置体系的核心。Environment会按优先级加载各种配置源:命令行参数 > 系统属性 > application.properties/yml文件 > 默认配置。
ApplicationContext创建与准备
根据之前推断的应用类型创建对应的ApplicationContext。接下来进入context准备阶段:设置Environment到context中,执行所有ApplicationContextInitializer的initialize方法,注册启动类为Bean定义,加载其他Bean定义。
核心刷新阶段
调用ApplicationContext的refresh()方法,这是Spring框架的经典流程:
BeanFactory准备:设置类加载器、表达式解析器等基础组件。
后处理器执行:执行所有BeanFactoryPostProcessor,其中最重要的是ConfigurationClassPostProcessor,它会解析@Configuration、@ComponentScan、@Import等注解,完成Bean定义的注册。
Bean实例化:按照依赖关系顺序实例化所有单例Bean。这个过程中会处理@Autowired、@Value等注解,完成依赖注入。
Web服务器启动:如果是Web应用,这个阶段会启动内嵌的Tomcat、Jetty或Undertow服务器。
启动完成处理
refresh完成后,调用afterRefresh方法执行一些收尾工作。随后通知所有监听器应用已启动完成,最后查找并执行所有ApplicationRunner 和CommandLineRunner实现类。
启动完成
返回创建完成的ApplicationContext容器实例,整个SpringBoot应用启动流程结束。
总结
当面试官问到SpringBoot启动流程时,你需要把握以下要点:
- 两个核心阶段:SpringApplication创建和run方法执行
- 应用类型推断决定了ApplicationContext类型
- Environment是配置管理的核心,有明确的优先级
- refresh是Spring容器启动的经典流程