【SpringBoot】程序启动流程
基本的SpringBoot的应用程序,有两个重要元素:
- 注解:@SpringBootApplication
- 启动方法:SpringApplication.run(FirstBootApplication.class, args) ;
1、@SpringBootApplication注解
1 @Target(ElementType.TYPE) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Documented 4 @Inherited 5 @SpringBootConfiguration 6 @EnableAutoConfiguration 7 @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), 8 @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) 9 public @interface SpringBootApplication { 10 11 @AliasFor(annotation = EnableAutoConfiguration.class) 12 Class<?>[] exclude() default {}; 13 14 @AliasFor(annotation = EnableAutoConfiguration.class) 15 String[] excludeName() default {}; 16 17 @AliasFor(annotation = ComponentScan.class, attribute = "basePackages") 18 String[] scanBasePackages() default {}; 19 20 @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses") 21 Class<?>[] scanBasePackageClasses() default {}; 22 23 @AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator") 24 Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class; 25 26 27 @AliasFor(annotation = Configuration.class) 28 boolean proxyBeanMethods() default true; 29 }
- @SpringBootConfiguration 配置类SpringBoot社区推荐基于JavaConfig配置方式定义Bean
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration public @interface SpringBootConfiguration {
- @EnableAutoConfigurationSpringBoot实现自动配置的关键
@Enable开头的注解,替代XML配置文件, @EnableWebMvc、@EnableScheduling // 注解之所以自动根据条件注册需要的Bean实例,主要是@Import注解导入此处@Import导入AutoConfigurationImportSelector的实现。
1 @Target(ElementType.TYPE) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Documented 4 @Inherited 5 @AutoConfigurationPackage 6 @Import(AutoConfigurationImportSelector.class) 7 public @interface EnableAutoConfiguration { 8 9 String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; 10 11 Class<?>[] exclude() default {}; 12 13 String[] excludeName() default {}; 14 }
AutoConfigurationImportSelector的selectImports -> getCandidateConfigurations -> SpringFactoriesLoader.loadFactoryNames
List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct."); return configurations; }
类SpringFactoriesLoader定义常量 public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
而spring-boot-autoconfigure*.jar/META-INF/spring.factories部分配置
spring-boot*jar\META-INF\spring.factories 部分
2、SpringApplication.run
内部实现流程
1、如果使用run静态方法,那么该方法实例化一个SpringApplication对象,调用如下方法
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
}
初始化时,提前做几个事情(准备动作)
- 根据classpath是否存在某特征类,决定是否创建供web应用使用的ApplicationContext类型
- 使用SpringFactoriesLoader在应用classpath查找并加载所有可用的ApplicationContextInitializer,
- 使用SpringFactoriesLoader在应用classpatch查找并加载所有可用ApplicationListener
2、SpingApplication实例初始化完成并完成设置后,开始执行run方法,首先遍历执行所有通过SpringFactoriesLoader查找到并加载的SpringApplicationRunListener,调用他们的Starting方法
3、准备并配置当前spring boot应用要使用的Enviroment(含PropertySource和Profiles)
protected void configureEnviroment(ConfirugurableEnviroment enviroment,String[] args){
configurePropertySources(enviroment, args);
configureProfiles(enviroment, args);
}
4、遍历执行所有SpringApplicationRunListener的enviromentPrepared() 方法,比如创建ApplicationContext
5、判断SpringApplication的bannerMode,是CONSOLE则输出banner的System.out,是OFF则不打印,是LOG则打印到日志文件
6、判断是否设置ApplicationContextClass属性,如果有,则实例化该class;如果没有则判断是否是web环境,如果是DEFAULT_WEB_CONTEXT_CLASS,则实例化该常量对应的AnnotationConfigEmbeddedWebApplicationContext类,否则实例化DEFAULT_CONTEXT_CLASS所对应的AnnotationConfigApplicationContext类,具体如下
public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context.annotation.AnnotationConfigApplicationContext";
public static final String DEFAULT_WEB_CONTEXT_CLASS = "org.springframework.context.embedded.AnnotationConfigEmbeddedWebApplicationContext";
7、将之前准备好的enviroment配置给当前的ApplicationContext
8、将beanNameGenerator、resourceLoader配置给当前的ApplicationContext
9、SpringApplication通过SpringFactoriesLoader查找classpath中所有可用的AppliContextInitializer,遍历并加载ApplicationContextInitializer的initialize(context) 方法
10、遍历执行所有SpringApplicationRunListener的contextPrepared() 方法
11、为BeanDefinitionLoader配置beanNameGenerator、‘resourceLoader、enviroment,并加载之前通过@EnableAutoConfiguration获取的所有配置,及其余IOC容器配置到当前已准备完毕的ApplicationContext
12、遍历执行所有SpringApplicationRunListener的contextLoader()方法
13、调用ApplicationContext的refresh方法,完成IOC容器可用的最后工序,并为Runtime.getRuntime()添加ShutdownHook以遍JVM停止时优雅退出
14、查找ApplicationContext是否注册ApplicationRunner或CommandLineRunner,并遍历执行
15、遍历执行SpringApplicationRunListener的finished() 方法。
-- 启动完成
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· 单线程的Redis速度为什么快?
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码