详解Spring Boot 启动时执行特定代码逻辑的实现方案

书接上回,我们总结了Spring Boot启动过程中都干了些什么,大致分为环境配置、IOC容器bean加载、事件通知等,具体详细总结可自行调转查看。今天我们来看看一个平时在业务开发中常见的逻辑场景。在开发 Spring Boot 应用时,我们经常需要在项目启动时执行一些初始化逻辑,比如加载缓存、连接外部系统、初始化配置信息等。Spring Boot 提供了多种实现方式,允许我们在应用启动的不同阶段插入代码逻辑。本文将结合启动过程详细介绍这些方式,并说明适用的场景及实现示例。


接下来我将一一讲述实现方式,这些操作的源码流程已经在启动过程总结一文中详细叙述过, 这里就只做定义解析和案例展示了,关于源码实现细节可跳转链接查看哈。

1. 使用 CommandLineRunner 和 ApplicationRunner

CommandLineRunnerApplicationRunner 是 Spring Boot 提供的两个接口,用于在应用启动完成后执行逻辑。

  • CommandLineRunner 接收 String[] args 参数,适合处理简单的启动参数。
  • ApplicationRunner 接收 ApplicationArguments 对象,方便解析复杂参数。

CommandLineRunner 示例:

java 复制代码
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
​
@Component
public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("执行 CommandLineRunner 逻辑!");
        for (String arg : args) {
            System.out.println("启动参数:" + arg);
        }
    }
}

ApplicationRunner 示例:

java 复制代码
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
​
@Component
public class MyApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("执行 ApplicationRunner 逻辑!");
        if (args.containsOption("debug")) {
            System.out.println("调试模式启动!");
        }
    }
}

适用场景: 在项目启动后立即执行初始化逻辑,例如加载缓存或注册服务。这是笔者比较推荐的方式,用的最多~~~


2. 使用 ApplicationListener 监听启动事件

Spring 提供了丰富的 事件机制 。通过实现 ApplicationListener 接口,我们可以监听应用启动的各个阶段事件,如 ApplicationReadyEvent

示例:

typescript 复制代码
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
​
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationReadyEvent> {
    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        System.out.println("应用启动完成,执行 ApplicationReadyEvent 事件监听逻辑!");
    }
}

适用场景: 当需要在应用完全启动后执行某些操作,如向监控系统注册实例。


3. 使用 @EventListener 注解

@EventListener 注解是一种简化的事件监听机制,允许我们用注解监听特定事件。

java 复制代码
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
​
@Component
public class MyEventListener {
​
    @EventListener(ApplicationStartedEvent.class)
    public void onApplicationStarted() {
        System.out.println("Spring Boot 启动时,执行 ApplicationStartedEvent 监听逻辑!");
    }
}

适用场景: 适用于监听特定事件,如应用启动或关闭时的操作。

上面使用监听事件的两种方式分别监听了事件ApplicationReadyEventApplicationStartedEvent,同类型的事件如下所示,这里就不一一讲述了,感兴趣的可自行写写示例体会下。


项目推荐:基于SpringBoot2.x、SpringCloud和SpringCloudAlibaba企业级系统架构底层框架封装,解决业务开发时常见的非功能性需求,防止重复造轮子,方便业务快速开发和企业技术栈框架统一管理。引入组件化的思想实现高内聚低耦合并且高度可配置化,做到可插拔。严格控制包依赖和统一版本管理,做到最少化依赖。注重代码规范和注释,非常适合个人学习和企业使用

Github地址github.com/plasticene/...

Gitee地址gitee.com/plasticene3...

微信公众号Shepherd进阶笔记

交流探讨qun:Shepherd_126

4. 使用 @PostConstruct 注解

@PostConstruct 注解用于在 Bean 初始化完成后执行逻辑。这是一个标准的 Java 注解,Spring 会在依赖注入完成后调用它标注的方法。

示例:

kotlin 复制代码
​
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
​
@Service
public class MyService {
    @PostConstruct
    public void init() {
        System.out.println("Bean 初始化完成后执行 @PostConstruct 方法!");
    }
}

适用场景: 当需要在某个 Bean 初始化完成后执行逻辑,比如连接数据库、加载外部资源等。


5. 使用 BeanPostProcessor

BeanPostProcessor 接口允许我们在 Bean 初始化前后插入逻辑。

示例:

typescript 复制代码
​
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
​
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
​
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化前处理 Bean:" + beanName);
        return bean;
    }
​
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化后处理 Bean:" + beanName);
        return bean;
    }
}

适用场景: 当需要对某些 Bean 的初始化过程进行增强时。


6. 使用 InitializingBean 接口

InitializingBean 接口中的 afterPropertiesSet() 方法会在 Bean 的属性设置完成后执行。

示例:

java 复制代码
​
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
​
@Component
public class MyInitializingBean implements InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Bean 属性设置完成,执行 afterPropertiesSet() 方法!");
    }
}

适用场景: 当需要在 Bean 初始化后执行一些逻辑。


7. 使用 SmartInitializingSingleton 接口

SmartInitializingSingleton 是一个特殊接口,当 所有单例 Bean 初始化完成后 ,会触发 afterSingletonsInstantiated() 方法。

示例:

typescript 复制代码
​
import org.springframework.context.SmartInitializingSingleton;
import org.springframework.stereotype.Component;
​
@Component
public class MySmartInitializingSingleton implements SmartInitializingSingleton {
    @Override
    public void afterSingletonsInstantiated() {
        System.out.println("所有单例 Bean 初始化完成,执行 afterSingletonsInstantiated() 方法!");
    }
}

适用场景: 当需要确保所有单例 Bean 初始化完成后再执行操作。


8. 在 main 方法中执行逻辑

在 Spring Boot 应用的入口方法 main 中,我们也可以执行一些初始化逻辑。

示例:

typescript 复制代码
​
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
​
@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        System.out.println("Spring Boot 启动前,执行自定义逻辑!");
        SpringApplication.run(MyApplication.class, args);
        System.out.println("Spring Boot 启动后,执行自定义逻辑!");
    }
}

适用场景: 当需要在应用启动的前后执行全局逻辑时。


总结

实现方式 触发时机 适用场景
CommandLineRunner 应用启动完成后 需要执行启动参数相关逻辑
ApplicationRunner 应用启动完成后 更方便处理复杂启动参数
@PostConstruct Bean 初始化完成后 Bean 的初始化逻辑
ApplicationListener 特定事件触发时 监听应用启动或关闭的事件
@EventListener 特定事件触发时 使用注解简化事件监听
BeanPostProcessor Bean 初始化前后 增强 Bean 的初始化过程
InitializingBean Bean 属性设置完成后 属性注入后的初始化逻辑
SmartInitializingSingleton 所有单例 Bean 初始化完成后 所有 Bean 完成初始化后的逻辑
main方法 应用启动前后 在应用启动前或启动后执行全局逻辑

选择合适的实现方式

  • 需要在应用启动后立即执行逻辑CommandLineRunnerApplicationRunner
  • 需要监听应用的启动事件ApplicationListener@EventListener
  • 需要对 Bean 初始化过程进行控制@PostConstructBeanPostProcessor
  • 需要确保所有 Bean 初始化完成后再执行逻辑SmartInitializingSingleton

不同的实现方式适用于不同的场景,我们可以根据业务需求选择合适的方式,将逻辑插入到 Spring Boot 启动的不同阶段。

相关推荐
未秃头的程序猿9 分钟前
Java 26正式发布!这3个新特性,让代码量直接减半
java·后端·面试
小旭Coding32 分钟前
卧靠!Go 传给前端的 int64 竟然变成了这个?
后端
用户2986985301433 分钟前
Word 文档文本查找与替换的 Java 实现方案
java·后端
阿哉36 分钟前
Nacos 服务发现源码:藏在背后的两套事件机制,90%的人只讲了一半
java
kunge201336 分钟前
深度剖析Claude Code 的CLAUDE.md加载逻辑
后端·vibecoding
米沙AI37 分钟前
MSYS2 快速使用版本
后端
Csvn1 小时前
Docker 进阶 — 网络模型、数据持久化与多阶段构建
后端
用户4279254051711 小时前
《微博开放平台官方CLI开源了:70+API一行搞定,AI Agent原生支持》
后端
Csvn1 小时前
文本处理三剑客 — grep、sed、awk 实战精讲
后端