Java 后端面试题库 / 全部题解免费阅读理解原理,有条理地回答

启动时怎样执行指定代码?

查看完整题解

参考回答

直接回答

常用 ApplicationRunner 或 CommandLineRunner,在容器启动流程中执行初始化任务;前者接收解析后的应用参数,后者接收原始字符串数组。多个runner可按顺序规则组织,但不应依赖未声明的扫描先后。它们不是HTTP请求,也不是每个实例只会在整个集群里执行一次。

讲清原理

runner运行时容器已准备好,适合短小、幂等且启动必需的检查。ApplicationReadyEvent位于成功执行runner之后,不能把容器刷新完成事件、runner与真正就绪完全视为同一时刻。

抛出的失败会影响启动结果;长时间任务可能延后就绪。集群每个实例都会经历自身启动,所以迁移、发券等动作还需专门协调,不能只放runner就假定全局唯一。

runner执行完成后才进入成功就绪阶段
runner执行完成后才进入成功就绪阶段

例子与易错点

示例可读取任务模式并打印不含秘密的确认信息。必须失败就停止的检查可以明确抛异常;可延后执行的工作应交给受控任务机制,不在启动线程中无限等待外部服务。

以下为 Java 21 类成员示例,放入同一外部类中使用,依赖 Boot4.1.2 / Framework7.0.10。实际非Web启动核对两个runner顺序及就绪事件,不代表集群只执行一次。

@org.springframework.boot.SpringBootConfiguration
static class RunnerApp {
    static final java.util.List<String> LOG=new java.util.ArrayList<>();
    @org.springframework.context.annotation.Bean
    @org.springframework.core.annotation.Order(1)
    org.springframework.boot.ApplicationRunner first() {
        return args -> LOG.add("first:"+args.getOptionValues("mode").getFirst());
    }
    @org.springframework.context.annotation.Bean
    @org.springframework.core.annotation.Order(2)
    org.springframework.boot.CommandLineRunner second() { return args -> LOG.add("second"); }
    @org.springframework.context.event.EventListener(org.springframework.boot.context.event.ApplicationReadyEvent.class)
    void ready() { LOG.add("ready"); }
}

相关题:第 8 题、第 32 题、第 62 题。

这道题,你掌握得怎么样?

掌握程度由你主动标记,阅读和收藏不会自动改变状态。