Spring Boot项目完全启动后执行某个方法的方式

在 Spring Boot 项目中,如果你想在应用完全启动后执行某个方法,有以下几种常见方式:


✅ 1. 使用 @EventListener(ApplicationReadyEvent.class)

这是 最推荐 的方式,会在 Spring Boot 启动完全完成后执行。

import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class StartupListener {

    @EventListener(ApplicationReadyEvent.class)
    public void onApplicationReady() {
        // 在此处调用你的业务方法
        System.out.println("应用已完全启动,执行定制逻辑...");
        myService.doSomethingAfterStartup();
    }

    @Resource
    private MyService myService;
}
  • 📌 优点:所有 Bean 都初始化完成,外部服务也准备就绪。
  • ⚠️ 建议:如逻辑耗时,可使用异步线程执行,避免阻塞主线程。

🔄 2. 实现 ApplicationRunner(或 CommandLineRunner

这两个接口均继承``org.springframework.boot.Runner接口,在 SpringApplication.run()` 完成后调用,用于执行初始化逻辑。

示例:使用 ApplicationRunner

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class MyAppStartupRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) {
        System.out.println("ApplicationRunner:应用上下文已加载,开始执行初始化...");
        myService.doSomethingAfterStartup();
    }

    @Resource
    private MyService myService;
}
  • 🆚 CommandLineRunner 接口类似,但参数不同(String[] args)。
  • 📌 适用场景:执行命令行任务或简单初始化逻辑。

🧠 3. 实现 SmartLifecycle 接口(高级控制)

适用于需要精细控制启动顺序组件生命周期的场景。

🧩 接口结构

SmartLifecycle 继承自 Lifecycle 接口,定义了 6 个方法:

public interface SmartLifecycle extends Lifecycle {

    boolean isAutoStartup();         // 是否自动启动

    void stop(Runnable callback);   // 停止时的回调钩子

    int getPhase();                 // 控制启动和关闭的顺序(phase 越小越早)

}
方法名说明
start()应用启动时调用
stop()应用关闭时调用
isRunning()返回是否正在运行
getPhase()控制启动/关闭顺序,数字越小越早
isAutoStartup()返回是否随 Spring 启动自动运行
stop(Runnable cb)关闭时回调,执行完必须调用 cb.run()

🚀 启动和关闭顺序控制(phase)

  • 启动顺序:phase 值小的组件 先启动
  • 停止顺序:phase 值大的组件 先停止

示例

package cn.datangyun.admin;

import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component;

@Component
public class AppSmartService implements SmartLifecycle {

    private boolean running = false;

    // 在Spring 应用上下文刷新完成后执行
    @Override
    public void start() {
        System.out.println("SmartLifecycle - 启动任务执行...");
        running = true;
    }

    // 从 Lifecycle 接口继承,Spring 容器关闭(例如调用 context.close() 或 JVM 关闭)时被调用
    @Override
    public void stop() {
        System.out.println("SmartLifecycle - 停止任务执行...");
        running = false;
    }

    @Override
    public boolean isRunning() {
        return running;
    }

    @Override
    public boolean isAutoStartup() {
        return true; // 启动时自动执行 start()
    }

    // SmartLifecycle 特有,Spring 容器关闭(例如调用 context.close() 或 JVM 关闭)时被调用
    @Override
    public void stop(Runnable callback) {
        System.out.println("SmartLifecycle - 回调停止逻辑...");
        stop();         // 先执行正常 stop()
        callback.run(); // 通知容器“我已经停好了”
    }

    @Override
    public int getPhase() {
        return 100; // 控制启动/停止顺序(默认是 0)
    }
}

📌 适用场景

启动后执行任务调度初始化(但需在某些 Bean 启动之后)

应用关闭时优雅释放连接、线程、缓存

在多个组件中设置启动顺序,比如启动组件 A 之后再启动组件 B

🆚 与其他生命周期接口的区别

接口用途适用场景
InitializingBeanBean 初始化后调用简单初始化逻辑
@PostConstructBean 创建后执行方法初始化资源
ApplicationRunner应用上下文加载完成后调用启动时执行任务
SmartLifecycle控制整个 Spring 应用启动流程控制组件启动顺序 / 生命周期管理

📋 总结对比表

方式触发时机是否推荐特点说明
@EventListener(ApplicationReadyEvent)Spring Boot 完全启动后✅ 推荐所有组件初始化完成,最可靠
ApplicationRunner / CommandLineRunnerSpringApplication.run() 执行完✅ 推荐简单初始化任务,使用方便
SmartLifecycle所有 Bean 初始化后、按 phase 顺序调用🚫 一般更灵活,适合控制启动/关闭流程

如需执行任务较重的初始化逻辑,建议结合 @Async 或线程池异步执行,避免阻塞主线程影响服务启动速度。

人生不作安期生,醉入东海骑长鲸