You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot:如何调整嵌入式容器的SmartLifecycle阶段优先级

解决方案

要实现计算任务优雅停止后再关闭Web服务器,可以通过调整WebServerGracefulShutdownLifecycle的阶段值来实现,具体步骤如下:

1. 调整Web服务器的生命周期阶段

Spring Boot默认的WebServerGracefulShutdownLifecycle阶段是Integer.MAX_VALUE,我们可以通过BeanPostProcessor在该Bean初始化前修改它的阶段值,让它低于自定义任务的生命周期阶段:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.web.context.WebServerGracefulShutdownLifecycle;
import org.springframework.stereotype.Component;

@Component
public class WebServerPhaseAdjuster implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof WebServerGracefulShutdownLifecycle) {
            // 将Web服务器的阶段设为比最大值小100,给自定义任务留出更高阶段
            ((WebServerGracefulShutdownLifecycle) bean).setPhase(Integer.MAX_VALUE - 100);
        }
        return bean;
    }
}

2. 实现自定义任务的优雅停止生命周期

创建一个SmartLifecycle组件,设置更高的阶段值(比如Integer.MAX_VALUE),确保它的stop()方法在Web服务器关闭前执行,并且在方法内阻塞直到所有计算任务完成:

import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@Component
public class TaskGracefulShutdown implements SmartLifecycle {
    private volatile boolean running = false;
    private final ExecutorService taskExecutor = Executors.newFixedThreadPool(5);

    @Override
    public void start() {
        running = true;
        // 启动计算任务示例
        for (int i = 0; i < 10; i++) {
            taskExecutor.submit(() -> {
                try {
                    Thread.sleep(2000);
                    System.out.println("计算任务执行完成");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }
    }

    @Override
    public void stop() {
        // 优雅关闭线程池,等待所有任务完成
        taskExecutor.shutdown();
        try {
            if (!taskExecutor.awaitTermination(30, TimeUnit.SECONDS)) {
                taskExecutor.shutdownNow();
            }
        } catch (InterruptedException e) {
            taskExecutor.shutdownNow();
            Thread.currentThread().interrupt();
        }
        System.out.println("所有计算任务已完成,Web服务器即将关闭");
        running = false;
    }

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

    @Override
    public int getPhase() {
        // 设置比Web服务器调整后的阶段更高的值
        return Integer.MAX_VALUE;
    }
}

原理说明

Spring的SmartLifecycle停止逻辑是按阶段值从大到小执行:自定义任务的阶段值更高,所以stop()会先被调用,此时Web服务器仍在运行,可正常处理指标、健康检查请求;等自定义任务的stop()执行完毕(即计算任务全部完成),才会执行Web服务器的优雅关闭逻辑。

内容的提问来源于stack exchange,提问作者Azmisov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 19:47:33