本文最后更新于 2024-11-04,文章内容可能已经过时。

在Spring Boot应用启动后立即执行一些操作,可以通过多种方式实现。

Ⅰ. 使用 CommandLineRunner

CommandLineRunner 是一个接口,其实现类的 run 方法会在应用启动后立即执行。你可以通过实现这个接口来执行一些启动后的操作。

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.err.println("Application has started and is running CommandLineRunner");
        log.info("Application has started and is running CommandLineRunner");
    }
}

Ⅱ. 使用 ApplicationRunner

ApplicationRunner 类似于 CommandLineRunner,但它提供了更丰富的命令行参数处理功能。

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class MyApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.err.println("Application has started and is running ApplicationRunner");
        log.info("Application has started and is running ApplicationRunner");
    }
}

Ⅲ. 监听 ApplicationReadyEvent

ApplicationReadyEvent 是一个特殊的事件,表示应用已经完全启动并且准备就绪。你可以通过监听这个事件来执行一些启动后的操作。

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class AppStartupRunner {

    @EventListener(ApplicationReadyEvent.class)
    public void runAfterStartup() {
        System.err.println("Application has started and is ready");
        // 在这里执行你的操作,例如连接数据库并刷新数据
        log.info("Application has started and is ready");
    }
}

Ⅳ. 使用 @PostConstruct

虽然 @PostConstruct 标记的方法会在依赖注入完成后立即调用,但它通常用于单个Bean的初始化,而不是整个应用启动后的操作。

import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class MyBean {

    @PostConstruct
    public void init() {
        System.err.println("MyBean initialized");
        // 这里可以做一些初始化操作,但不是整个应用启动后的操作
        log.info("MyBean initialized");
    }
}

Ⅴ. 使用 SmartLifecycle

SmartLifecycle 接口允许你在应用上下文加载完成后启动一些后台任务或定时任务。

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class MySmartLifecycle implements SmartLifecycle {

    private boolean running = false;

    @Override
    public void start() {
        System.err.println("Starting MySmartLifecycle");
        log.info("Starting MySmartLifecycle");
        running = true;
        // 在这里执行你的操作,例如启动后台任务
    }

    @Override
    public void stop() {
        System.err.println("Stopping MySmartLifecycle");
        log.info("Stopping MySmartLifecycle");
        running = false;
    }

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

    // 其他方法可以根据需要实现
}

总结

2024-11-04T14:39:18.301+08:00  INFO 2992 --- [java-demo] [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2024-11-04T14:39:18.301+08:00  INFO 2992 --- [java-demo] [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2024-11-04T14:39:18.874+08:00  INFO 2992 --- [java-demo] [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
2024-11-04T14:39:18.888+08:00  INFO 2992 --- [java-demo] [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-11-04T14:39:18.888+08:00  INFO 2992 --- [java-demo] [  restartedMain] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.31]
2024-11-04T14:39:18.924+08:00  INFO 2992 --- [java-demo] [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-11-04T14:39:18.924+08:00  INFO 2992 --- [java-demo] [  restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 622 ms
MyBean initialized
2024-11-04T14:39:18.964+08:00  INFO 2992 --- [java-demo] [  restartedMain] com.nn3n.javademo.after.MyBean           : MyBean initialized
2024-11-04T14:39:19.162+08:00  INFO 2992 --- [java-demo] [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2024-11-04T14:39:19.190+08:00  INFO 2992 --- [java-demo] [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
2024-11-04T14:39:19.191+08:00  INFO 2992 --- [java-demo] [  restartedMain] c.nn3n.javademo.after.MySmartLifecycle   : Starting MySmartLifecycle
2024-11-04T14:39:19.197+08:00  INFO 2992 --- [java-demo] [  restartedMain] com.nn3n.javademo.JavaDemoApplication    : Started JavaDemoApplication in 1.199 seconds (process running for 1.646)
2024-11-04T14:39:19.199+08:00  INFO 2992 --- [java-demo] [  restartedMain] c.n.javademo.after.MyCommandLineRunner   : Application has started and is running CommandLineRunner
2024-11-04T14:39:19.199+08:00  INFO 2992 --- [java-demo] [  restartedMain] c.n.javademo.after.MyApplicationRunner   : Application has started and is running ApplicationRunner
2024-11-04T14:39:19.200+08:00  INFO 2992 --- [java-demo] [  restartedMain] c.nn3n.javademo.after.AppStartupRunner   : Application has started and is ready
2024-11-04T14:39:19.200+08:00  INFO 2992 --- [java-demo] [  restartedMain] com.nn3n.javademo.JavaDemoApplication    : Application started
Starting MySmartLifecycle
Application has started and is running CommandLineRunner
Application has started and is running ApplicationRunner
Application has started and is ready

以上方法都可以在Spring Boot应用启动后立即执行一些操作。选择哪种方法取决于你的具体需求:

  • CommandLineRunnerApplicationRunner:适用于执行一些简单的启动后操作,如打印日志或执行一些初始化任务。
  • ApplicationReadyEvent:适用于需要在应用完全启动后执行的操作,如连接数据库并刷新数据。
  • SmartLifecycle:适用于需要启动后台任务或定时任务的场景。