Spring Boot 钩子全集实战(一):构造与配置阶段

Spring Boot 钩子全集实战(一):构造与配置阶段

在使用 Spring Boot 时,我们通常这样启动一个应用:

typescript 复制代码
@SpringBootApplication
public class DemoApplication {
    public static void void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

看起来简洁明了,对吧?但在这短短几行代码背后,Spring Boot 其实悄悄为我们预留了多个"钩子",这些扩展点允许我们在应用启动的不同阶段注入自定义逻辑。

接下来,我将推出一个系列文章,带你系统掌握 Spring Boot 各个阶段的钩子机制。今天是第一篇:构造与配置阶段,通俗易懂、代码可运行!

一、什么是"构造与配置阶段"?

简单来说,就是你创建 SpringApplication 对象到执行run方法之前的这段时间。

这个阶段的关键特点是:还没有真正启动 Spring 容器!

二、该阶段的有哪些钩子?

在这一阶段,我们主要通过配置 SpringApplication 实例来注入自定义行为,常见钩子有:

钩子方法 类型 作用
addInitializers(...) 方法调用 手动添加 ApplicationContextInitializer,用于在容器刷新前修改上下文
addListeners(...) 方法调用 手动添加 ApplicationListener,监听 Spring 事件
setXXX(...) 系列 方法调用 设置主类、Banner 模式、Web 类型等

三、 应用场景 + 代码示例

1. addInitializers(...)

应用场景
  • 在 Spring 容器刷新(refresh)之前,对 ApplicationContext 进行自定义配置,比如设置环境变量、注册自定义 Bean 定义、修改上下文的属性源等。
  • 适用于需要在容器初始化早期注入全局配置的场景,例如多环境配置增强、自定义属性加载、权限相关的上下文初始化等。
代码示例
java 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(DemoApplication.class);

        // 自定义 ApplicationContextInitializer
        ApplicationContextInitializer<ConfigurableApplicationContext> customInitializer = context -> {
            // 获取环境配置
            ConfigurableEnvironment environment = context.getEnvironment();
            // 新增自定义环境变量
            environment.getSystemProperties().put("custom.app.name", "SpringHookDemo");
            // 打印初始化日志
            System.out.println("ApplicationContext 初始化前:添加自定义环境变量 custom.app.name");
        };

        // 添加初始化器(钩子方法)
        application.addInitializers(customInitializer);

        // 启动应用
        ConfigurableApplicationContext context = application.run(args);

        // 验证:获取并打印自定义变量
        String appName = context.getEnvironment().getProperty("custom.app.name");
        System.out.println("启动后获取的自定义变量:" + appName);
    }
}
执行结果
vbnet 复制代码
ApplicationContext 初始化前:添加自定义环境变量 custom.app.name
启动后获取的自定义变量:SpringHookDemo

2. addListeners(...)

应用场景
  • 监听 Spring Boot 生命周期中的核心事件(如 ApplicationStartedEventApplicationReadyEventApplicationFailedEvent 等),实现自定义的事件响应逻辑。
  • 典型场景:应用启动成功后发送通知(邮件 / 钉钉)、启动失败时记录告警日志、监听上下文刷新事件做数据预热等。
代码示例
typescript 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationListener;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.boot.context.event.ApplicationReadyEvent;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(DemoApplication.class);

        // 监听应用启动事件(Started:容器已启动,但未处理请求)
        ApplicationListener<ApplicationStartedEvent> startedListener = event -> {
            System.out.println("事件监听:应用已启动(Started),开始初始化业务数据...");
            // 模拟:初始化缓存、加载字典数据等
        };

        // 监听应用就绪事件(Ready:可处理请求)
        ApplicationListener<ApplicationReadyEvent> readyListener = event -> {
            System.out.println("事件监听:应用已就绪(Ready),发送启动成功通知...");
            // 模拟:调用通知接口、记录启动日志等
        };

        // 添加事件监听器(钩子方法)
        application.addListeners(startedListener, readyListener);

        // 启动应用
        application.run(args);
    }
}
执行结果
erlang 复制代码
事件监听:应用已启动(Started),开始初始化业务数据...
事件监听:应用已就绪(Ready),发送启动成功通知...

3. setXXX(...) 系列方法

应用场景
  • setMainApplicationClass(Class<?> mainApplicationClass):手动指定应用主类(默认自动识别,特殊场景下需显式指定);
  • setBannerMode(Banner.Mode mode):控制启动 Banner 的显示(关闭 / 控制台 / 日志文件);
  • setWebApplicationType(WebApplicationType type):指定应用的 Web 类型(NONE:非 Web 应用、SERVLET:Servlet 容器、REACTIVE:响应式 Web);
  • setAdditionalProfiles(String... profiles):设置额外的激活配置文件(如测试 / 生产环境)。
代码示例(常用 set 方法组合)
arduino 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.Banner;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(DemoApplication.class);

        // 1. 关闭启动 Banner
        application.setBannerMode(Banner.Mode.OFF);

        // 2. 指定为非 Web 应用(即使引入 Web 依赖,也不会启动 Tomcat 等容器)
        application.setWebApplicationType(WebApplicationType.NONE);

        // 3. 激活 test 配置文件
        application.setAdditionalProfiles("test");

        // 4. 手动指定主类(可选,默认自动识别)
        application.setMainApplicationClass(DemoApplication.class);

        // 启动应用
        application.run(args);
        System.out.println("非 Web 应用启动完成,激活的配置文件:test");
    }
}
执行结果
bash 复制代码
非 Web 应用启动完成,激活的配置文件:test

(注:启动时不会显示 Spring Boot 的默认 Banner,也不会启动 Tomcat 容器)

四、总结

  1. addInitializers 核心作用是容器刷新前修改上下文,适用于早期全局配置注入;
  2. addListeners 用于监听 Spring 事件,实现启动 / 运行阶段的自定义响应逻辑;
  3. setXXX 系列是配置 SpringApplication 核心属性,覆盖 Banner、Web 类型、配置文件等基础行为。

这些钩子均在 SpringApplication.run() 执行前调用

📌 关注我 ,每天5分钟,带你从 Java 小白变身编程高手!

👉 点赞 + 关注+转发,让更多小伙伴一起进步!

👉 私信"SpringBoot钩子源码" 获取源码!

相关推荐
二哈赛车手1 小时前
新人笔记---ApiFox的一些常见使用出错
java·笔记·spring
栗子~~2 小时前
JAVA - 二层缓存设计(本地缓冲+redis缓冲+广播所有本地缓冲失效) demo
java·redis·缓存
YDS8292 小时前
DeepSeek RAG&MCP + Agent智能体项目 —— RAG知识库的搭建和接口实现
java·ai·springboot·agent·rag·deepseek
发现一只大呆瓜3 小时前
Vite凭什么这么快?3分钟带你彻底搞懂 Vite 热更新的幕后黑手
前端·面试·vite
未若君雅裁3 小时前
MyBatis 一级缓存、二级缓存与清理机制
java·缓存·mybatis
AI人工智能+电脑小能手4 小时前
【大白话说Java面试题 第65题】【JVM篇】第25题:谈谈对 OOM 的认识
java·开发语言·jvm
阿维的博客日记4 小时前
Nacos 为什么能让配置动态生效?(涉及 @RefreshScope 注解)
java·spring
雨辰AI4 小时前
SpringBoot3 + 人大金仓读写分离 + 分库分表 + 集群高可用 全栈实战
java·数据库·mysql·政务
Patrick_Wilson5 小时前
知识沉淀的四层模型:从个人笔记到企业资产,让文档真正长出复利
面试·程序员·ai编程
辰海Coding6 小时前
MiniSpring框架学习-完成的 IoC 容器
java·spring boot·学习·架构