Spring Boot 启动后自动执行 Service 方法终极指南
**导语:**在 Spring Boot 开发中,我们经常需要在应用启动后立即执行初始化任务(如加载配置、预热缓存、启动定时任务)。本文将深度解析 5 种主流实现方案,包含完整代码示例、执行顺序控制技巧和避坑指南!
一、为什么需要启动后自动执行方法?
典型使用场景
场景类型 | 具体案例 | 技术价值 |
---|---|---|
数据初始化 | 加载字典数据到内存 | 提升接口响应速度 |
定时任务启动 | 启动分布式任务调度 | 确保任务在服务就绪后执行 |
资源预加载 | 预热 Redis 缓存 | 避免冷启动导致的性能波动 |
参数校验 | 检查必要配置项是否存在 | 增强系统健壮性 |
第三方服务注册 | 向服务注册中心注册实例 | 保障微服务可用性 |
二、六大实现方案全解析
方案 1:@PostConstruct(简单初始化)
java
@Service
public class CacheInitializer {@PostConstructpublic void init() {// 在 Bean 初始化完成后执行loadAllConfigToCache();System.out.println("字典数据加载完成");}
}
特点:
- 执行时机:依赖注入完成后立即执行
- 适用场景:单 Bean 的简单初始化
- 注意:无法处理跨 Bean 依赖
方案 2:ApplicationRunner(参数解析增强)
java
@Component
@Order(1) // 控制执行顺序
public class StartupRunner implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) {// 解析命令行参数boolean force = args.containsOption("force");String configFile = args.getOptionValues("config").get(0);// 执行初始化逻辑System.out.println("使用参数启动:force="+force+", configFile="+configFile);}
}
优势:
- 支持命令行参数解析
- 天然支持 @Order 排序
方案 3:ApplicationListener
java
@Component
public class ApplicationReadyListener {@EventListener(ApplicationReadyEvent.class)public void onApplicationReady() {// 确保所有 Bean 初始化完成System.out.println("所有组件就绪,执行最终初始化");}
}
特殊价值:
- 可监听多个应用事件(如 ApplicationStartingEvent)
- 适合需要延迟执行的场景
方案 4:CommandLineRunner(基础参数处理)
java
@Component
public class ConfigLoader implements CommandLineRunner {@Overridepublic void run(String... args) {// 处理原始命令行参数System.out.println("原始参数:"+Arrays.toString(args));}
}
适用场景: 仅需处理字符串参数的场景
方案 5:自定义监听器(复杂流程控制)
java
@Component
public class StartupListener implements ApplicationListener<ContextRefreshedEvent> {@Overridepublic void onApplicationEvent(ContextRefreshedEvent event) {if (event.getApplicationContext().getParent() == null) {// 只在根上下文初始化时执行System.out.println("根上下文初始化完成");}}
}
高级用法:
- 防止多次触发(通过上下文判断)
- 结合 @Async 实现异步初始化
方案 6:@Scheduled 定时启动(延迟执行)
java
@Component
@EnableScheduling
public class DelayedInitializer {@Scheduled(fixedDelay = 5000) // 首次延迟5秒后执行public void delayedInit() {System.out.println("延迟初始化任务执行");}
}
特殊场景: 需要延迟执行的初始化任务
三、方案对比决策矩阵
方案 | 执行时机 | 参数支持 | 执行顺序 | 适用复杂度 |
---|---|---|---|---|
@PostConstruct | Bean | 初始化后 | 无 | 无 |
ApplicationRunner | 应用启动完成 | 解析参数 | 支持 | ★★★☆☆ |
ApplicationListener | 应用事件触发 | 无 | 需手动 | ★★★★☆ |
@Scheduled | 定时触发 | 无 | 无 | ★★☆☆☆ |
四、完整落地流程
步骤 1:创建初始化 Service
java
@Service
public class StartupService {public void initConfig() {// 加载配置逻辑}public void warmUpCache() {// 缓存预热逻辑}
}
步骤 2:选择执行方案(以 ApplicationRunner 为例)
java
@Component
@Order(1)
public class StartupRunner implements ApplicationRunner {private final StartupService startupService;public StartupRunner(StartupService startupService) {this.startupService = startupService;}@Overridepublic void run(ApplicationArguments args) {startupService.initConfig();startupService.warmUpCache();}
}
步骤 3:配置执行顺序(多初始化任务时)
java
@Component
@Order(2)
public class SecondaryInitializer implements CommandLineRunner {// 次级初始化任务
}
五、避坑指南与最佳实践
1. 循环依赖陷阱
java
// 错误示例:A 依赖 B,B 依赖 A
@Service
public class AService {private final BService bService;public AService(BService bService) {this.bService = bService;}@PostConstructpublic void init() {bService.doSomething(); // 触发循环依赖}
}
解决方案: 使用 @Lazy 延迟加载
2. 异步执行配置
java
@EnableAsync
@Configuration
public class AsyncConfig {@Beanpublic Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setQueueCapacity(100);return executor;}
}// 在方法上添加异步执行
@Async
public void asyncInit() {// 异步初始化逻辑
}
3. 执行顺序控制
java
@Component
@Order(1) // 数字越小优先级越高
public class FirstInitializer implements ApplicationRunner {}@Component
@Order(2)
public class SecondInitializer implements ApplicationRunner {}
六、生产环境验证方案
1. 单元测试
java
@SpringBootTest
class StartupTest {@Autowiredprivate StartupService startupService;@Testvoid testInitSequence() {// 验证初始化顺序verifyOrder(startupService::initConfig, startupService::warmUpCache);}
}
2. 日志监控
log
2025-04-09 09:00:00.000 INFO 12345 --- [ main] c.e.demo.StartupRunner : === 应用启动初始化开始 ===
2025-04-09 09:00:00.100 INFO 12345 --- [ main] c.e.demo.CacheInitializer : 字典数据加载完成(耗时85ms)
2025-04-09 09:00:00.200 INFO 12345 --- [ main] c.e.demo.StartupRunner : === 所有初始化任务完成 ===
七、扩展场景方案
1. 分布式锁控制(防重复执行)
java
@PostConstruct
public void distributedInit() {RLock lock = redissonClient.getLock("startup:init");if (lock.tryLock(0, 60, TimeUnit.SECONDS)) {try {// 执行初始化} finally {lock.unlock();}}
}
2. 健康检查联动
java
@EventListener(ApplicationReadyEvent.class)
public void healthCheck() {HealthIndicator indicator = context.getBean(HealthIndicator.class);if (!indicator.health().getStatus().equals(Status.UP)) {throw new RuntimeException("依赖服务未就绪");}
}
八、总结与选择建议
需求场景 | 推荐方案 |
---|---|
简单初始化 | @PostConstruct |
需要参数处理 | ApplicationRunner |
需要监听应用状态 | ApplicationListener |
延迟执行 | @Scheduled |
复杂初始化流程 | 自定义监听器 + 异步执行 |
公众号:【码农小站】
相关文章:
Spring Boot 启动后自动执行 Service 方法终极指南
**导语:**在 Spring Boot 开发中,我们经常需要在应用启动后立即执行初始化任务(如加载配置、预热缓存、启动定时任务)。本文将深度解析 5 种主流实现方案,包含完整代码示例、执行顺序控制技巧和避坑指南&a…...
STM32 HAL库之GPIO示例代码
LED灯不断闪烁 GPIO初始化,main文件中的 MX_GPIO_Init(); 也就是在 gpio.c文件中 void MX_GPIO_Init(void) {GPIO_InitTypeDef GPIO_InitStruct {0};/* GPIO Ports Clock Enable */__HAL_RCC_GPIOE_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOA_C…...
中间件-消息队列
SpringAMQP 任何语言只要遵循AMAP协议,都可以与RabbitMQ交互 生产者、队列、交换机、消费者 生产者Publisher:生产消息,发给交换机 交换机Exchange:接收生产者发送的消息。知道如何处理消息,例如递交给某个特别队列、…...
go游戏后端开发32:自摸杠处理逻辑
当我们在自摸杠时,实际上在杠完之后,我们还需要进行一个删除操作。因此,我们需要在上面拷贝一个删除操作。由于这是自摸杠,所以这个地方需要删除四次。在这里,我们需要注意的是,自摸杠时,传过来…...
AI创业风向标:构建下一代「AI叙事创作平台」
随着技术的进步和市场需求的爆发,AI故事叙述平台正成为投资者和创业者关注的焦点。本文将探讨为何这一赛道值得关注,并提供一些关于如何构建成功的AI叙事创作平台的战略建议。 一、为什么这是2025年值得关注的赛道? 1. 底层需求的爆发 人类永恒的故事需求:全球每月有超过…...
拜特科技签约惠生工程,携手打造高效资金管理系统
近日,拜特科技成功签约惠生工程(中国)有限公司(以下简称“惠生工程”)资金管理系统项目。此次双方携手打造一套先进的资金管理系统,为惠生工程的战略发展注入强劲新动力,推动其资金管理迈向更高水平。 惠生工程作为行…...
快瞳宠物肢体关键点检测:让宠物设备更懂“猫言狗语”
在宠物经济高速发展的今天,智能设备已渗透到养宠生活的方方面面。然而,如何让设备真正理解宠物的行为意图?快瞳科技推出的宠物肢体关键点检测技术,通过精准捕捉宠物肢体动作,为智能喂食、健康监测、行为训练等场景提供…...
【安卓】APP生成器v1.0,生成属于你的专属应用
今天作者给大家分享一个超级好用的手机APP。还在为反复搜索常用网站抓狂?今天安利一款颠覆性神器——它能将你所有心头好的网页变成专属按钮,像搭乐高一样DIY你的「软件」,从此告别收藏夹混乱!小说党、资讯控、摸鱼达人集体狂喜&a…...
详细解读react框架中的hooks
React Hooks 是 React 16.8 引入的一项革命性特性,它允许你在函数组件中使用状态(state)和其他 React 特性,而无需编写 class 组件。下面将详细解读 React Hooks 的核心概念、常用 Hooks 及其工作原理。 一、Hooks 的核心概念 1. 什么是 Hooks Hooks …...
机器学习01-支持向量机(SVM)(未完)
参考浙大 胡浩基老师 的课以及以下链接: https://blog.csdn.net/m0_74100344/article/details/139560508 https://blog.csdn.net/2301_78630677/article/details/132657023 https://blog.csdn.net/lsb2002/article/details/131338700 一、一些定义 T是倒置&…...
Java进阶版线程池(超详细 )
线程池 线程池工具类 Executors Executors 是 Java 提供的一个工具类,它包含了多个静态方法,能够方便地创建不同类型的线程池。 newFixedThreadPool 创建一个固定大小的线程池,线程池中的线程数量固定,当有新任务提…...
场外期权只适合上涨行情吗?
场外期权与直接进行期货市场操作相比,场外期权让我们有了更多的选择空间。”目前期权市场有了更多合适的风险管理模式,场外期权衍生品工具与其需求不谋而合,适合做以小博大,做各种对冲大盘下跌风险等等策略,下文为大家…...
echarts图表相关
echarts图表相关 echarts官网折线图实际开发场景一: echarts官网 echarts官网 折线图 实际开发场景一: 只有一条折线,一半实线,一半虚线。 option {tooltip: {trigger: "axis",formatter: (params: any) > {const …...
【操作系统(Linux)】——多线程对共享变量访问的同步与互斥
一、多线程对共享变量的非互斥访问 我们将要做的:构造多线程共享变量竞争的案例,并分析现象发生的原因,进而思考解决方式。 案例源代码: #include <stdio.h> #include <stdlib.h> #include <pthread.h> #inc…...
deeplabv3+街景图片语义分割,无需训练模型,看不懂也没有影响,直接使用,cityscapes数据集_16
目录 1、下载链接1.1、CSDN链接,含权重文件直接使用,建议直接下这个,还不限速。1.2 Github链接: 2、下载代码,下载预训练好的权重3、预测代码4、像素提取,或者说类别提取5、文档部分内容截图6、其他数据处理…...
[前端]从人体结构看网页三要素:HTML、CSS 与 JavaScript
目录 一、HTML:网页的 “骨架” 二、CSS:网页的 “血肉” 三、JavaScript:网页的 “神经系统” 四、三者协同构建精彩网页 在互联网的浩瀚海洋中,网页是我们与世界交互的重要窗口。一个精彩的网页背后,离不开 HTML、CSS 和 JavaScript 这三位 “幕后英雄”。有趣的是,…...
【Leetcode】3375. 使数组的值全部为 K 的最少操作次数
文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接🔗 给你一个整数数组 nums 和一个整数 k 。 如果一个数组中所有 严格大于 h 的整数值都 相等 ,那么我们称整数 h 是 合法的 。 比方说,如果 nums [10, 8, 10…...
封装uniapp request promise化
uniapp request 封装 一、 封装方法1. 使用 promis 封装 request2. 封装 api 在 api.js3.在要请求的页面 调用 api 一、 封装方法 1. 使用 promis 封装 request const BASE_URL 你的url接口 //比如 http://198.12.3.3/pzexport function request(config {}){let {url,dat…...
架构演进成熟度校验体系构建
架构演进成熟度校验体系构建 ——基于电商价格服务Checklist的图形化实践指南 一、成熟度校验全景视图 #mermaid-svg-tXchQ6nY7QzNUrL1 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-tXchQ6nY7QzNUrL1 .error-ico…...
Llama 4全面评测:官方数据亮眼,社区测试显不足之处
引言 2025年4月,Meta正式发布了全新的Llama 4系列模型,这标志着Llama生态系统进入了一个全新的时代。Llama 4不仅是Meta首个原生多模态模型,还采用了混合专家(MoE)架构,并提供了前所未有的上下文长度支持。本文将详细介绍Llama 4…...
kotlin 多个fragment beginTransaction容器添加使用
在Kotlin中如何使用Fragment的beginTransaction来添加多个Fragment到容器中。我需要先回顾一下Fragment的基本用法,然后考虑多个Fragment的情况。 FragmentTransaction的beginTransaction是用来开启一个事务,然后添加、替换或移除Fragment。通常&#x…...
(PTA) L2-011-L2-015
L2-012 关于堆的判断 由于没有得到AC代码(1,3测试点错误),这里先不做展示,等后续复盘的时候进行补充。 L2-011 玩转二叉树 给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序…...
管理Linux服务器的用户和组
用户/组 命令符会展示当前用户名和主机名 创建用户,同时创建同名组 useradd 用户名 设置密码 passwd 用户名 切换用户登录 su 用户名 删除用户 userdel -r 用户名 记录用户信息的文件 /etc/passwd 记录密码(密文)信息的文件 /etc/sh…...
奇安信驻场面试题
《网安面试指南》https://mp.weixin.qq.com/s/RIVYDmxI9g_TgGrpbdDKtA?token1860256701&langzh_CN 5000篇网安资料库https://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247486065&idx2&snb30ade8200e842743339d428f414475e&chksmc0e4732df793fa3bf39…...
Testbench设计
一、几个名词: 被仿真的文件叫DUT(Design under Test) 编写Testbench的目的 验证设计有没问题。 怎么写Testbench? 四、Teshbench各个部分的写法: 外部信号就是外面连接的信号。...
使用IPython有哪些好处?
这里总结了50个使用IPython的好处,大大提升开发效率! 什么是IPython?可能很多人已经在用,却不知道它到底是什么。 根据维基百科的解释: IPython是一种基于Python的交互式解释器,提供了强大的编辑和交互功能…...
加油站小程序实战教程10开通会员
目录 1 修改用户登录逻辑2 创建变量3 调用API总结 我们上一篇搭建了开通会员的界面,有了界面的时候就需要加入一些逻辑来控制界面显示。我们的逻辑是当用户打开我的页面的时候,在页面加载完毕后调用API看用户是否已经开通会员了,如果未开通就…...
NO.84十六届蓝桥杯备战|动态规划-路径类DP|矩阵的最小路径和|迷雾森林|过河卒|方格取数(C++)
路径类dp是线性dp的⼀种,它是在⼀个nm的矩阵中设置⼀个⾏⾛规则,研究从起点⾛到终点的⽅案数、最⼩路径和或者最⼤路径和等等的问题 矩阵的最小路径和_牛客题霸_牛客网 状态表⽰: dp[i][j]表⽰:到达[i, j]位置处,最⼩…...
WHAT - React 技术栈常用库/工具
目录 基础类状态管理路由管理UI 组件库开发工具 / 辅助库测试相关表单和数据展示其它实用类代码重构应用迁移:PWA代码组织与架构建议(选项) 下面是一个 React 技术栈常用库/工具清单,按不同分类整理,涵盖开发、状态管理…...
FreeSWITCH的SIP配置
确认 FreeSWITCH 的 SIP 配置 FreeSWITCH 的 SIP 配置文件通常位于 /usr/local/freeswitch/conf/sip_profiles 目录下。默认情况下,FreeSWITCH 使用 internal.xml 和 external.xml 作为 SIP 配置文件。 查看 internal.xml 配置 编辑 /usr/local/freeswitch/conf/sip…...
Spark核心知识总结
一、Spark运行架构 (一)整体结构 Spark框架采用标准master - slave结构,Driver为master管理作业任务调度,Executor为slave负责实际执行任务。 (二)核心组件 1. Driver:执行Spark任务的main方法&…...
第1节:计算机视觉发展简史
计算机视觉与图像分类概述:计算机视觉发展简史 计算机视觉(Computer Vision)作为人工智能领域的重要分支,是一门研究如何使机器"看"的科学,更具体地说,是指用摄影机和计算机代替人眼对目标进行识…...
2D 与 3D 连线效果全解析 | 从平面到立体
HT 是一个灵活多变的前端组件库,具备丰富的功能和效果,满足多种开发需求。让我们将其效果化整为零,逐一拆解具体案例,帮助你更好地理解其实现方案。 在此篇文章中,让我们一起深入探讨 2D 与 3D 的连线效果是如何实现的…...
Django Cookies 实际项目示例
Django Cookies 实际项目示例 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 Django Cookies 实际项目示例介绍什么是 Django Cookies?为什么要关心 Django Cookies?Django Cookie…...
【问题排查】SQLite安装失败
启动 Django 自带的开发服务器 python manage.py runserver出现如下报错: [rootiZ2zedudtf2cwzi9argky2Z myproject]# python manage.py runserver Watching for file changes with StatReloader Performing system checks...System check identified no issues (…...
stream流Collectors.toMap(),key值重复问题
文章目录 一、问题二、问题示例三、原因四、解决方法4.1、方案一 一、问题 发现Collectors.toMap的一个坑,若key值重复的时候会抛异常。如: IllegalStateException: Duplicate key 男 二、问题示例 报错示例如下: import lombok.AllArgsC…...
STM32(基于标准库)
参考博客:江科大STM32笔记 Stm32外设 一、GPIO 基础 GPIO位结构 I/O引脚的保护二极管是对输入电压进行限幅的上面的二极管接VDD, 3.3V,下面接VSS, 0V,当输入电压 >3.3V 那上方这个二极管就会导通,输入电压产生的电流就会大部分充入VD…...
OpenStack Yoga版安装笔记(十八)Self-service networks配置笔记
1、官方文档 在OpenStack官方安装文档中,提供了两个网络配置选项: Option1:Provider networksOption2:Self-service networks 这两个选项并不冲突,可以在OpenStack环境中同时配置。 在《OpenStack Yoga版安装笔记&…...
2025年黑龙江建筑安全员 C3 证考试题库练习题
黑龙江建筑安全员 C3 证考试题库练习题 1、消防控制室是设有火灾自动报警设备和消防设施控制设备,用于接收、显示、处理( ),控制相关消防设施的专门处所2。 A. 安全信息 B. 设备信息 C. 通讯信号 D. 火灾报警信号 答案&…...
JavaScript数据结构-Map的使用
在 JavaScript 中,Map 是 ES6 引入的一种新的数据结构,它类似于对象,也是键值对的集合,但 Map 的键可以是任意类型的值(对象、函数、基本类型等),而传统对象的键只能是字符串或 Symbolÿ…...
LeetCode面试经典150题
目录 力扣80. 删除有序数组中的重复项 II 代码解析 力扣274. H 指数 代码解析 力扣151. 反转字符串中的单词 解析代码 力扣12. 整数转罗马数字 解析代码 力扣28. 找出字符串中第一个匹配项的下标 解析代码1(暴力模拟) 解析代码2(K…...
mysql之等值连接8个实例
以下实例以常见的业务场景为例,使用 MySQL 语法,假设存在员工表(employees)、部门表(departments)、订单表(orders)、客户表(customers)等,来展示…...
C基础笔记_指针专题
一:C 和 C 偏爱使用指针的原因 1. 通过指针可以直接操作内存 C 和 C 是系统级编程语言,它们的设计目标之一是允许开发者直接与硬件交互并高效地管理资源。 指针的本质:指针本质上是一个存储内存地址的变量,它让程序员可以直接访问和操作内…...
GPT-SoVITS Windows 配置与推理笔记(自用)
GPT-SoVITS Windows 配置与推理笔记(自用) 这是给自己留的备份,方便下次查。Windows 端配置和推理为主,代码为核心,直接干货。 环境准备 系统:Windows 10/11Python:3.9(别用别的版…...
【设计模式】面向对象开发学习OOPC
PLOOC-裸机思维 PLOOC OOPC精要——撩开“对象”的神秘面纱 C/C面向对象编程之封装-KK 面向过程,本质是“顺序,循环,分支”面向对象,本质是“继承,封装,多态”参考的书籍:《UMLOOPC嵌入式C语言…...
LVGL开发指南
一、主流ARM开发UI界面库 主流ARM开发UI界面库的详细对比分析,从多个维度评估各库的适用场景: 1. 基础对比表 特性LVGLQt for MCUEmbedded WizardTouchGFXemWin许可证MIT开源商业商业商业(STM32免费)商业RAM最小需求16KB512KB64KB256KB50KBFlash占用64KB+1MB+200KB+500KB+1…...
linux shell looop循环写法
在 Linux Shell 中编写loop循环的常见方法有以下几种,适用于持续执行任务或监控场景: 1. while true 循环(最常用) while true; do# 循环体内的命令echo "Running..."sleep 1 # 避免 CPU 占用过高 done 终止方式&…...
【力扣hot100题】(075)数据流的中位数
一开始只建立了一个优先队列,每次查询中位数时都要遍历一遍于是喜提时间超限,看了答案才恍然大悟原来还有这么聪明的办法。 方法是建立两个优先队列,一个大根堆一个小根堆,大根堆记录较小的数,小根堆记录较大的数。 …...
蓝桥杯刷题总结 + 应赛技巧
当各位小伙伴们看到这篇文章的时候想必蓝桥杯也快开赛了,那么本篇文章博主就来总结一下一些蓝桥杯的应赛技巧,那么依旧先来走个流程 那么接下来我们分成几个板块进行总结 首先是一些基本语法 编程语言的基本语法 首先是数组,在存数据的时候…...
JetBrains Terminal 又发布新架构,Android Studio 将再次迎来新终端
不到一年的时间,JetBrains 又要对 Terminal 「大刀阔斧」,本次发布的新终端是重构后的全新的架构,而上一次终端大调整还是去年 8 月的 v2024.2 版本,并且在「Android Studio Ladybug | 2024.2.1」也被引入。 不知道你们用不用内置…...