如何在Quarkus应用完全启动后执行代码?
在所有Bean创建完成、应用完全运行后执行代码的方法
你已经了解@Startup和启动观察者,这里给你几种精准适配「所有Bean创建完成、应用完全运行后」执行代码的方案:
1. 监听ContextRefreshedEvent事件
Spring容器在所有Bean实例化、配置完成后会发布ContextRefreshedEvent事件,通过实现ApplicationListener接口即可监听:
import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.stereotype.Component; @Component public class PostStartupTask implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent event) { // 存在父子容器(如Spring MVC场景)时,事件可能触发多次,需判断根容器避免重复执行 if (event.getApplicationContext().getParent() == null) { // 这里编写要执行的初始化代码 System.out.println("所有Bean已创建,应用状态就绪,执行启动后任务"); } } }
2. 使用@EventListener注解
无需实现接口,直接在方法上标注@EventListener指定事件类型,写法更简洁:
import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; @Component public class PostStartupTasks { @EventListener(ContextRefreshedEvent.class) public void runAfterStartup(ContextRefreshedEvent event) { if (event.getApplicationContext().getParent() == null) { // 执行你的业务初始化逻辑 System.out.println("应用启动完成,执行后续任务"); } } }
3. Spring Boot专属:CommandLineRunner或ApplicationRunner
如果是Spring Boot应用,这两个接口会在**应用完全启动(包括Web服务器就绪)**后执行,比ContextRefreshedEvent更贴合「应用完全运行」的场景:
CommandLineRunner示例
import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class StartupRunner implements CommandLineRunner { @Override public void run(String... args) throws Exception { // 应用完全启动后执行代码 System.out.println("应用已完全运行,执行初始化任务"); } }
ApplicationRunner示例(支持解析启动参数)
import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; @Component public class AppStartupRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { // 可通过args获取应用启动参数 System.out.println("应用完全启动,启动参数:" + args.getSourceArgs()); // 编写你的初始化逻辑 } }
注意事项
ContextRefreshedEvent会在容器刷新时触发,存在父子容器时可能多次执行,需通过根容器判断避免重复。CommandLineRunner和ApplicationRunner是Spring Boot特有,执行时机晚于ContextRefreshedEvent,确保应用已处于完全运行状态。
内容的提问来源于stack exchange,提问作者simonC
相关产品推荐
相关产品推荐

