当前位置: 首页 > article >正文

SpringBoot与Quartz深度整合:动态任务管理与Job中Bean注入的实战解析

1. 为什么需要SpringBoot与Quartz整合在企业级应用开发中定时任务是一个再常见不过的需求了。你可能用过Spring自带的Scheduled注解它确实简单好用只需要在方法上添加一个注解就能实现定时执行。但实际项目中我们往往需要更灵活的控制能力 - 比如根据用户操作动态启停任务、运行时修改执行频率、或者需要更复杂的调度策略。这时候就需要引入专业的任务调度框架Quartz了。我遇到过这样一个真实案例一个物联网平台需要根据设备状态动态调整数据采集频率。设备在线时每10秒采集一次进入省电模式后改为每分钟采集这种动态调整的需求用Scheduled根本无法实现。而Quartz提供了完整的API让我们可以随时修改任务触发规则。不过直接使用Quartz会遇到一个棘手问题 - Job类中无法直接注入Spring管理的Bean。这是因为Quartz自己管理Job实例的生命周期而Spring对这些实例一无所知。想象一下你的定时任务需要调用Service层的方法或者访问数据库这时候发现所有Autowired注解都失效了是不是很抓狂2. Quartz核心概念快速掌握2.1 Quartz的四大金刚Quartz的架构设计非常清晰主要包含四个核心组件Scheduler调度器的老大所有任务都要通过它来安排。你可以把它想象成公司的HR部门负责协调所有人员的调度安排。Job具体要执行的工作内容。就像公司里各个岗位的员工每个Job实现类代表一种具体职责。我通常会把业务逻辑封装在Service层Job中只保留最简化的调度逻辑。JobDetailJob的详细描述信息。这里有个关键点需要注意Quartz每次执行都会创建新的Job实例所以JobDetail中保存的是Job的蓝图而非实例本身。Trigger触发规则。就像员工的上班时间表可以简单如每天9点也可以复杂如每月最后一个周五避开节假日。Quartz支持两种主要触发器类型SimpleTrigger固定间隔触发CronTrigger基于Cron表达式的复杂调度2.2 为什么Job中不能直接注入Bean这个问题困扰过很多开发者。根本原因在于生命周期管理的冲突Quartz通过JobFactory创建Job实例完全独立于Spring容器Spring的依赖注入发生在Bean初始化阶段这两个过程没有任何交集就好比你在外面自己雇了个临时工(Quartz Job)而公司的办公用品(Spring Bean)只提供给正式员工使用。临时工想用复印机门都没有3. 动态任务管理实战3.1 基础环境搭建首先在pom.xml中添加依赖dependency groupIdorg.quartz-scheduler/groupId artifactIdquartz/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-quartz/artifactId /dependency建议使用spring-boot-starter-quartz它已经帮我们处理了很多基础配置比如自动配置SchedulerFactoryBean。3.2 动态调度核心实现创建一个QuartzScheduler工具类来封装常用操作Configuration public class QuartzScheduler { Autowired private Scheduler scheduler; // 创建并启动任务 public void scheduleJob(String jobName, String cron, Class? extends Job jobClass) throws SchedulerException { JobDetail jobDetail JobBuilder.newJob(jobClass) .withIdentity(jobName) .storeDurably() .build(); Trigger trigger TriggerBuilder.newTrigger() .withIdentity(jobName _Trigger) .withSchedule(CronScheduleBuilder.cronSchedule(cron)) .build(); scheduler.scheduleJob(jobDetail, trigger); } // 更新任务调度规则 public void rescheduleJob(String jobName, String newCron) throws SchedulerException { TriggerKey triggerKey TriggerKey.triggerKey(jobName _Trigger); CronTrigger newTrigger TriggerBuilder.newTrigger() .withIdentity(triggerKey) .withSchedule(CronScheduleBuilder.cronSchedule(newCron)) .build(); scheduler.rescheduleJob(triggerKey, newTrigger); } // 暂停任务 public void pauseJob(String jobName) throws SchedulerException { JobKey jobKey JobKey.jobKey(jobName); scheduler.pauseJob(jobKey); } // 恢复任务 public void resumeJob(String jobName) throws SchedulerException { JobKey jobKey JobKey.jobKey(jobName); scheduler.resumeJob(jobKey); } // 删除任务 public void deleteJob(String jobName) throws SchedulerException { JobKey jobKey JobKey.jobKey(jobName); scheduler.deleteJob(jobKey); } }这个工具类提供了完整的生命周期管理能力你可以通过REST API暴露这些方法实现前端动态控制。3.3 实际应用场景示例假设我们有一个电商促销系统需要在特定时间段执行不同的营销活动RestController RequestMapping(/schedule) public class ScheduleController { Autowired private QuartzScheduler quartzScheduler; // 启动双11预热任务 PostMapping(/start-preheat) public String startPreheat() throws SchedulerException { quartzScheduler.scheduleJob( preheatJob, 0 0 18 ? * MON-FRI, // 工作日每晚6点 PreheatJob.class ); return 预热任务已启动; } // 大促期间改为每5分钟执行 PostMapping(/enhance-frequency) public String enhanceFrequency() throws SchedulerException { quartzScheduler.rescheduleJob( preheatJob, 0 */5 * ? * * // 每5分钟 ); return 执行频率已提升; } }4. Job中注入Bean的三种解决方案4.1 Spring工具类方案这是最直接的解决方案创建一个SpringUtil工具类Component public class SpringContextHolder implements ApplicationContextAware { private static ApplicationContext context; Override public void setApplicationContext(ApplicationContext ctx) { context ctx; } public static T T getBean(ClassT beanClass) { return context.getBean(beanClass); } }然后在Job中这样使用public class OrderSyncJob implements Job { Override public void execute(JobExecutionContext context) { OrderService orderService SpringContextHolder.getBean(OrderService.class); orderService.syncLatestOrders(); } }这种方案的优点是简单直接缺点是破坏了依赖注入的原则而且需要小心处理空指针问题。4.2 自定义JobFactory方案更优雅的方式是自定义JobFactorypublic class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware { private transient AutowireCapableBeanFactory beanFactory; Override public void setApplicationContext(ApplicationContext context) { beanFactory context.getAutowireCapableBeanFactory(); } Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { Object job super.createJobInstance(bundle); beanFactory.autowireBean(job); return job; } }然后在配置类中注册Configuration public class QuartzConfig { Autowired private ApplicationContext applicationContext; Bean public SchedulerFactoryBean schedulerFactoryBean() { SchedulerFactoryBean factory new SchedulerFactoryBean(); AutowiringSpringBeanJobFactory jobFactory new AutowiringSpringBeanJobFactory(); jobFactory.setApplicationContext(applicationContext); factory.setJobFactory(jobFactory); return factory; } }这样配置后Job类中就可以直接使用Autowired了public class InventoryCheckJob implements Job { Autowired private InventoryService inventoryService; Override public void execute(JobExecutionContext context) { inventoryService.checkLowStockItems(); } }4.3 使用PersistJobDataAfterExecution注解对于需要保持状态的Job可以结合PersistJobDataAfterExecution使用PersistJobDataAfterExecution DisallowConcurrentExecution public class ReportGenerationJob implements Job { Autowired private ReportService reportService; Override public void execute(JobExecutionContext context) { JobDataMap dataMap context.getJobDetail().getJobDataMap(); String reportId dataMap.getString(reportId); reportService.generateReport(reportId); } }这种方式特别适合需要传递参数的周期性任务。5. 生产环境注意事项5.1 集群环境配置在生产环境中我们通常需要配置Quartz集群# application.properties spring.quartz.properties.org.quartz.jobStore.isClusteredtrue spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval20000 spring.quartz.properties.org.quartz.jobStore.driverDelegateClassorg.quartz.impl.jdbcjobstore.StdJDBCDelegate spring.quartz.properties.org.quartz.jobStore.tablePrefixQRTZ_记得在数据库中初始化Quartz表结构SQL脚本可以在Quartz发行包的docs/dbTables目录下找到。5.2 异常处理策略定时任务的异常处理需要特别注意public class SafeJob implements Job { private static final Logger logger LoggerFactory.getLogger(SafeJob.class); Override public void execute(JobExecutionContext context) { try { // 业务逻辑 } catch (Exception e) { logger.error(任务执行失败, e); // 根据业务需求决定是否重试 if(shouldRetry(e)) { throw new JobExecutionException(e, true); } } } private boolean shouldRetry(Exception e) { // 判断异常类型决定是否重试 return e instanceof TemporaryException; } }5.3 性能监控建议建议对任务执行情况进行监控public class MonitoredJob implements Job { Autowired private MetricsService metricsService; Override public void execute(JobExecutionContext context) { long start System.currentTimeMillis(); String jobName context.getJobDetail().getKey().getName(); try { // 业务逻辑 metricsService.recordSuccess(jobName, System.currentTimeMillis() - start); } catch (Exception e) { metricsService.recordFailure(jobName, e.getClass().getSimpleName()); throw e; } } }可以在Grafana等监控系统中展示任务执行时长、成功率等关键指标。

相关文章:

SpringBoot与Quartz深度整合:动态任务管理与Job中Bean注入的实战解析

1. 为什么需要SpringBoot与Quartz整合 在企业级应用开发中,定时任务是一个再常见不过的需求了。你可能用过Spring自带的Scheduled注解,它确实简单好用,只需要在方法上添加一个注解就能实现定时执行。但实际项目中,我们往往需要更灵…...

The Ultimate Guide to Ruby Timeouts:如何为第三方服务API设置超时

The Ultimate Guide to Ruby Timeouts:如何为第三方服务API设置超时 【免费下载链接】the-ultimate-guide-to-ruby-timeouts Timeouts for popular Ruby gems 项目地址: https://gitcode.com/gh_mirrors/th/the-ultimate-guide-to-ruby-timeouts 在Ruby开发中…...

优化DMA串口通信:避免数据覆盖的实战策略

1. DMA串口通信的数据覆盖问题解析 第一次遇到DMA串口通信数据覆盖问题时,我正在调试一个ADC采集项目。主函数里连续发送两条数据,结果接收端收到的数据总是残缺不全,第二条数据的前半部分莫名其妙地覆盖了第一条数据的后半段。当时我的第一反…...

Mitogen上下文管理实战:从本地到SSH的完整部署清单

Mitogen上下文管理实战:从本地到SSH的完整部署清单 【免费下载链接】mitogen Distributed self-replicating programs in Python 项目地址: https://gitcode.com/gh_mirrors/mi/mitogen Mitogen是一个基于Python的分布式自复制程序框架,通过高效的…...

Autodistill革命性AI工具:无需标注即可训练计算机视觉模型的终极指南

Autodistill革命性AI工具:无需标注即可训练计算机视觉模型的终极指南 【免费下载链接】autodistill Images to inference with no labeling (use foundation models to train supervised models). 项目地址: https://gitcode.com/gh_mirrors/au/autodistill …...

云端GPU实战:在AutoDL平台高效部署Llama2中文对话模型

1. 为什么选择云端GPU部署Llama2中文模型 最近在折腾大模型部署的朋友应该都深有体会,本地跑个13B参数的Llama2简直就像让自行车上高速——不是不行,是真费劲。我去年尝试在32G内存的工作站上部署7B版本,光是加载模型就花了15分钟&#xff0c…...

多变量赋值,解包,split()与eval()

input与split结合运用注意点:...

别再烧芯片了!手把手教你搞懂STM32 GPIO的过压保护二极管(附实测数据)

STM32 GPIO保护二极管实战指南:从原理到实测的完整避坑手册 刚拿到STM32开发板的新手们,总会遇到这样的灵魂拷问:为什么我的芯片又冒烟了?上周实验室里,小王同学用5V的超声波模块直接接到STM32的GPIO上,结果…...

AIAgent语音识别实战指南:2026奇点大会披露的7个工业级优化参数(附基准测试数据)

第一章:2026奇点智能技术大会:AIAgent语音识别全景洞察 2026奇点智能技术大会(https://ml-summit.org) 技术演进脉络 2026年大会首次系统性披露端到端语音识别模型在AIAgent场景中的泛化瓶颈突破路径。主流框架已从传统CTCAttention转向动态语义对齐&a…...

Pixel Aurora Engine保姆级教程:极光青主题CSS像素边框重绘技巧

Pixel Aurora Engine保姆级教程:极光青主题CSS像素边框重绘技巧 1. 认识Pixel Aurora Engine Pixel Aurora Engine是一款专为像素艺术创作设计的AI绘图工作站。它最大的特点是将现代AI技术与复古像素美学完美结合,创造出独特的视觉体验。 这个引擎最吸…...

如何处理旧版MongoDB升级到新版时密码哈希不兼容

bcrypt哈希值在MongoDB各版本间完全兼容,问题根源是认证机制升级:旧MONGODB-CR用户需重建为SCRAM-SHA-1,FCV须同步更新,驱动与连接字符串需显式指定authMechanism。bcrypt 哈希结果在新旧 MongoDB 版本间完全兼容,问题…...

【SPIE出版、EI检索稳定】2026年智慧油气与可持续发展国际学术会议(SOGSD 2026)

在全球能源转型与科技革命深度融合之际,智慧油气已成为推动行业高质量发展的核心动力。作为首届盛会,2026年智慧油气与可持续发展国际学术会议将于2026年5月29-31日在中国成都举行。SOGSD 2026旨在构建一个高水平的国际合作交流平台,聚焦人工…...

后 Zoom 时代:视频会议平台的多元竞争与选择

Google Meet:免费易用,AI 助力办公提效Google Meet 是多数使用 Google Workspace 团队的首选。它免费版就能支持 100 名参会者,且所有功能在浏览器中流畅运行,无需下载。其能自动从 Gmail 和日历提取会议详情,省去复制…...

【SPIE-电子科技大学主办】第三届计算机视觉、机器人与自动化工程国际学术会议(CRAE 2026)

第三届计算机视觉、机器人与自动化工程国际学术会议(CRAE 2026)将于2026年6月26-28日在成都举行。会议聚焦于计算机视觉、机器人与自动化工程等前沿研究领域,旨在为全球范围内的专家学者、工程技术人员和技术研发人员提供一个高效的平台。往届…...

为什么92%的AIAgent项目卡在世界建模阶段?深度拆解6个被忽略的感知-记忆-推理对齐断点

第一章:世界模型在AIAgent架构中的核心定位与失败率归因 2026奇点智能技术大会(https://ml-summit.org) 世界模型(World Model)并非AIAgent的可选组件,而是其认知闭环的底层基础设施——它承担着环境建模、状态推演、反事实规划与…...

【四川电影电视学院主办】第五届科学教育与艺术鉴赏国际学术会议(SEAA 2026)

第五届科学教育与艺术鉴赏国际学术会议(SEAA 2026)将于2026年6月26-28日在中国-成都召开。会议主要围绕会议主要围绕科学教育与艺术鉴赏以及影视教学、影视艺术、影视制作等研究领域展开讨论。旨在为该领域的专家学者及企业发展人提供一个分享研究成果、讨论存在的问题与挑战、…...

2025届学术党必备的六大降重复率工具解析与推荐

Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 对于维普系统检测AI生成内容的情况,要想降低AI率,得从文本特征调整这…...

2025届毕业生推荐的降AI率平台横评

Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 切实有效地降低知网AI检测率,为此特别建议采取下面这些策略:首先&…...

Gemma-3多模态大模型应用场景:盲文教材图片→文字转录+知识点提炼

Gemma-3多模态大模型应用场景:盲文教材图片→文字转录知识点提炼 1. 应用场景概述 盲文教材作为视障人群获取知识的重要载体,其数字化和智能化处理一直面临巨大挑战。传统的人工转录方式效率低下且成本高昂,而普通OCR技术又无法识别盲文点字…...

2025届最火的降AI率神器横评

Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 在AI生成内容越来越广泛地普及的大背景状况之下,怎样去有效减少文本所具有的机械…...

从零开始!手把手教你搭建一个会“思考“的外汇交易AI机器人(附源码)

作者:老余捞鱼 原创不易,转载请标明出处及原作者。 写在前面的话:今天跟大家分享我最新搭建的欧美外汇自动交易机器人。这套系统整合了EMA均线、RSI强弱指标、MACD趋势线和布林带四大经典武器,还加入了谷歌Gemini AI智能过滤层,能自动识别市场陷阱。从数据抓取到信号生成,…...

大模型应用开发实例学习笔记 - 大模型集成、RAG、Tool Calling、MCP协议、智能体.etc

大模型应用开发实例学习笔记 - 大模型集成、RAG、Tool Calling、MCP协议、智能体.etc 掌握基于Spring生态的AI应用开发,覆盖大模型集成、RAG、Tool Calling、MCP协议、智能体等核心场景。 Spring AI Alibaba 开源项目基于 Spring AI 构建,是阿里云通义系列模型及服务在 Java…...

嵌入式linux设备内存泄露排查思路

文章目录 引言: 一、快速确认 二、定位泄露源(内核态/用户态) 2.1 检查内核内存 2.2 检查用户态进程 三、使用工具排查泄露点 四、修复与验证 引言: 设备自己跑着跑着突然挂死了,还是靠看门狗给救回来了。这种时候,一定要考虑是不是内存泄露导致内存耗尽了。 那我们来看…...

rk3399平台rtl8723DS Wi-Fi模块SDIO接口驱动移植与双模配置实战

1. 认识rk3399与rtl8723DS这对黄金搭档 第一次拿到rk3399开发板和rtl8723DS模块时,我就像拿到新玩具的孩子一样兴奋。rk3399这颗六核处理器在嵌入式领域堪称性能怪兽,而rtl8723DS作为Wi-Fi蓝牙二合一模块,2.4GHz频段支持加上双模共存特性&…...

ubuntu命令行中文化脚本,个人用于解决“WSL中安装并使用cc-switch图形化界面乱码”问题

脚本内容:#!/bin/bashecho " WSL Ubuntu 中文环境配置脚本 "# 1. 安装中文 locale echo "[1/4] 安装中文语言包..." sudo apt update sudo apt install -y language-pack-zh-hans# 2. 生成并配置 locale echo "[2/4] 配置系统 locale...&q…...

保姆级教程:STM32+ESP8266接入机智云,从零完成数据点上报与APP控制

STM32与ESP8266接入机智云实战:从数据点定义到APP控制全解析 在智能硬件开发领域,快速实现设备联网与远程控制是许多嵌入式工程师面临的挑战。本文将手把手带您完成一个基于STM32和ESP8266的智能温湿度监测系统,从机智云平台配置到代码移植&a…...

GetQzonehistory:终极QQ空间历史说说备份指南,3步永久保存青春回忆

GetQzonehistory:终极QQ空间历史说说备份指南,3步永久保存青春回忆 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 想要永久保存QQ空间里那些珍贵的青春记忆吗&a…...

计算机网络 之 【HTTP协议】(hppt请求与响应细节、http版本与连接管理)

目录 1.http请求 1.1. http请求方法 1.2.http请求报头 2.http响应 2.1.http响应状态码及其描述 2.2.重定向 3.http版本简介 4.http连接管理 4.1.HTTP 连接管理基础 4.2.连接类型与演进 4.2.1.短连接(HTTP/1.0 默认) 4.2.2.长连接&#xff08…...

贵州辣椒酱:一份榜单,供参考

贵州辣椒酱:一份榜单,供参考贵州是全国最大的辣椒生产基地之一。辣椒酱在当地人的日常饮食中,算是比较基础的调味品。近几年,贵州辣椒酱的市场认知度逐渐提高,品牌也多了起来。2026年,贵州省辣椒产业协会发…...

从二极管整流到晶体管可变电阻:拆解一个学生设计的AGC电路反馈环工作原理

从二极管整流到晶体管可变电阻:拆解一个学生设计的AGC电路反馈环工作原理 在模拟电路设计的浩瀚海洋中,自动增益控制(AGC)电路犹如一位隐形的调音师,默默维持着电子信号的稳定输出。对于电子爱好者和高年级本科生而言&…...