Spring Boot的启动流程,以及各个扩展点的执行顺序
目录
1. 初始化阶段执行顺序
1.1 Bean的构造方法(构造函数)
1.2 @PostConstruct 注解方法
1.3 InitializingBean 的 afterPropertiesSet()
1.4 @Bean(initMethod = "自定义方法")
2. 上下文就绪后的扩展点
2.1 ApplicationContext 事件监听器
2.2 ApplicationRunner 与 CommandLineRunner
3. 完整执行顺序总结
4. 控制执行顺序的方法
5. 示例代码验证
在Spring Boot应用中,容器初始化及组件执行的顺序遵循特定的生命周期。以下是常见的初始化组件及其执行顺序的详细说明,帮助您合理控制代码逻辑的加载顺序。
1. 初始化阶段执行顺序
以下是Spring Boot应用启动时,各初始化方法的执行顺序(从上到下依次执行):
1.1 Bean的构造方法(构造函数)
- 触发时机:Bean实例化时。
- 说明:Bean被容器创建时,构造函数首先被调用。
@Component
public class MyBean {public MyBean() {System.out.println("构造方法执行");}
}
1.2 @PostConstruct
注解方法
- 触发时机:Bean依赖注入完成后。
- 说明:在Bean属性赋值(如
@Autowired
注入)之后执行。
@Component
public class MyBean {@PostConstructpublic void init() {System.out.println("@PostConstruct方法执行");}
}
1.3 InitializingBean
的 afterPropertiesSet()
- 触发时机:与
@PostConstruct
类似,但由Spring原生接口提供。 - 说明:在Bean属性设置完成后执行,优先于自定义的
init-method
。
@Component
public class MyBean implements InitializingBean {@Overridepublic void afterPropertiesSet() {System.out.println("InitializingBean的afterPropertiesSet执行");}
}
1.4 @Bean(initMethod = "自定义方法")
- 触发时机:在
@PostConstruct
和InitializingBean
之后执行。 - 说明:通过
@Bean
注解显式指定的初始化方法。
@Configuration
public class AppConfig {@Bean(initMethod = "customInit")public AnotherBean anotherBean() {return new AnotherBean();}
}public class AnotherBean {public void customInit() {System.out.println("@Bean的initMethod执行");}
}
2. 上下文就绪后的扩展点
当所有Bean初始化完成后,应用进入上下文就绪阶段:
2.1 ApplicationContext
事件监听器
ContextRefreshedEvent
监听器:当ApplicationContext
初始化或刷新完成后触发。@Component public class MyContextListener {@EventListener(ContextRefreshedEvent.class)public void onContextRefreshed() {System.out.println("ContextRefreshedEvent事件触发");} }
2.2 ApplicationRunner
与 CommandLineRunner
- 触发时机:在上下文就绪后、应用启动完成前执行。
- 执行顺序:通过
@Order
或实现Ordered
接口控制多个Runner的顺序。@Component @Order(1) public class MyAppRunner implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) {System.out.println("ApplicationRunner执行");} }@Component @Order(2) public class MyCmdRunner implements CommandLineRunner {@Overridepublic void run(String... args) {System.out.println("CommandLineRunner执行");} }
3. 完整执行顺序总结
以下是典型场景下各组件的执行顺序:
- Bean构造函数 →
@PostConstruct
→InitializingBean
→@Bean(initMethod)
ContextRefreshedEvent
监听器ApplicationRunner
→CommandLineRunner
4. 控制执行顺序的方法
@Order
注解:为ApplicationRunner
、CommandLineRunner
和事件监听器指定优先级,值越小优先级越高。@DependsOn
注解:强制指定Bean的依赖关系,间接影响初始化顺序。- 实现
Ordered
接口:替代@Order
注解,动态控制顺序。
5. 示例代码验证
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}
输出结果:
构造方法执行
@PostConstruct方法执行
InitializingBean的afterPropertiesSet执行
@Bean的initMethod执行
ContextRefreshedEvent事件触发
ApplicationRunner执行
CommandLineRunner执行
通过理解这些执行顺序,您可以更精准地安排初始化逻辑(如数据库连接、缓存预热等),避免因顺序问题导致的依赖错误。