Spring Boot如何在项目启动成功后执行一段初始化逻辑

背景说明

在我们使用Spring Boot进行项目开发时,偶尔会遇到在Spring Boot项目启动完成后需要执行一些初始化的逻辑,比如缓存预加载,数据库初始化等。 那么这种需求我们需要怎么实现呢?本文将提供3种方法供大家参考。


一、入门级:启动main方法中添加初始化逻辑

在Spring Boot的main入口启动方法中,执行SpringApplication.run(LimitApplication.class, args)是可以返回ApplicationContext对象的,我们可以从ApplicationContext中获取指定的bean对象,执行初始化逻辑。

@SpringBootApplication(scanBasePackages = {"com.laowan.limit"})
public class LimitApplication {

    public static void main(String[] args){
        //启动的run方法
        ApplicationContext context =  SpringApplication.run(LimitApplication.class, args);

        //启动执行操作:从context中获取指定的bean,调度初始化逻辑
        AService aService = (AService)context.getBean("AServiceImpl");
        aService.preLoadCache();
    }

}

初始化逻辑:

@Service
public class AServiceImpl implements AService {
    @Override
    public void preLoadCache(){
        System.out.println("应用启动完成:可以执行缓存预加载操作");
    }
}

二、黄金级:实现ApplicationRunner或CommandLineRunner接口

在Spring Boot框架中,给我们提供了ApplicationRunner和CommandLineRunner接口来帮助我们解决项目启动后的初始化资源操作。
如果有多个ApplicationRunner、CommandLineRunner的实现类,可以通过@Order注解进行排序,参数值越小越早执行。

实现CommandLineRunner接口:

@Order(1)
@Component
@Slf4j
public class CommandLineRunnerImpl implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("应用启动完成:执行CommandLineRunner方法完成资源初始化");
    }
}

实现ApplicationRunner接口:

@Order(2)
@Component
@Slf4j
public class ApplicationRunnerImpl implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("应用启动完成:执行ApplicationRunner方法完成资源初始化");
    }
}

启动方法:

@SpringBootApplication(scanBasePackages = {"com.laowan.limit"})
public class LimitApplication {
    public static void main(String[] args){
        SpringApplication.run(LimitApplication.class, args);
    }
}

执行结果:

2023-06-01 10:50:20.158  INFO 24785 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2023-06-01 10:50:20.230  INFO 24785 --- [           main] com.laowan.limit.LimitApplication        : Started LimitApplication in 2.454 seconds (JVM running for 2.891)
应用启动完成:执行CommandLineRunner方法完成资源初始化
应用启动完成:执行ApplicationRunner方法完成资源初始化

源码分析:
在SpringApplication的run方法中,有这么一段核心代码

public ConfigurableApplicationContext run(String... args) {
                ……
try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            Banner printedBanner = this.printBanner(environment);
            context = this.createApplicationContext();
            context.setApplicationStartup(this.applicationStartup);
            this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
            this.refreshContext(context);
            this.afterRefresh(context, applicationArguments);

            //通知所有监听器:spring boot已经启动完成
            listeners.started(context);
            //调用所有Runner方法,即CommandLineRunner和ApplicationRunner
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            this.handleRunFailure(context, var10, listeners);
            throw new IllegalStateException(var10);
        }
           ……  
  }      

三、大神级:ApplicationListener监听启动完成事件

通过源码,我们发现在Spring Boot启动过程中,框架内部定义了很多事件SpringApplicationEvent,用来通知SpringApplicationRunListener监听器,以针对各种事件执行对应的逻辑处理。而Spring Boot启动完成的事件对应的是ApplicationStartedEvent,我们可以通过自定义监听器来监听ApplicationStartedEvent事件,然后执行初始化资源的相关操作。

@Component
public class StartedEventListener implements ApplicationListener<ApplicationStartedEvent> {
    @Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        System.out.println("应用启动完成,通知监听器执行缓存预加载操作");
    }
}

 

 

posted @   CharyGao  阅读(55)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示