# 不上Quartz,数据库表驱动定时任务:Timer+反射,运行时动态加载

张开发
2026/4/16 2:07:29 15 分钟阅读

分享文章

# 不上Quartz,数据库表驱动定时任务:Timer+反射,运行时动态加载
不上Quartz数据库表驱动定时任务Timer反射运行时动态加载非科班野生程序员深耕政务信息化20年。从VC到PB再到Java自研框架browise也打磨了十几年。最近整理框架代码发现不少简洁实用的决策写出来和大家聊聊。本文方案全程不依赖第三方调度框架纯JDK原生实现轻量、稳定、易运维。一、业务场景与痛点政务系统中存在大量定时任务定时同步数据、定时生成报表、定时清理过期记录、定时对账等。这类任务有三个典型特点执行周期可变今天每天执行明天可能改为每小时/每10分钟执行内网环境受限Quartz等框架依赖多、配置复杂内网部署与升级繁琐运维偏好简单运维人员习惯页面可视化管理拒绝修改XML/配置文件重启服务。Quartz功能强大但过重引入大量依赖包学习与维护成本高而政务系统多数定时需求仅需固定周期执行无需Cron表达式等高阶能力。因此自研一套轻量方案更贴合场景。二、整体方案设计核心思路数据库表存储任务配置 JDK Timer调度 反射动态实例化。数据库表存储任务全类名、执行周期、首次执行时间启动加载服务启动时读取任务表自动注册调度动态管理页面增删改配置无需重启服务即可生效纯JDK实现无第三方依赖兼容所有Java Web环境。三、数据库表设计核心新建定时任务配置表字段极简且够用以下为核心字段字段名类型说明idBIGINT主键classnameVARCHAR(255)任务类全限定名如com.browise.timer.SyncDataTaskperiodINT执行周期单位秒begintimeDATETIME首次执行时间为空则默认当前时间task_nameVARCHAR(100)任务名称便于页面识别statusTINYINT任务状态0停用/1启用设计优势运维通过页面直接操作数据修改周期、启停任务全程无代码、无配置文件改动。四、完整代码实现1. 核心控制器TimerContral.java提供任务CRUD、启动/停止调度、反射加载任务的完整能力。aoppoint// AOP切面代理bean(idtimer)// 注册到IoC容器responseMapping(key/timer)// 请求路由publicclassTimerContral{privatestaticfinalorg.apache.log4j.Loggerlogorg.apache.log4j.Logger.getLogger(TimerContral.class);// 1. 查询所有定时任务LoggerTransresponseMapping(key/searchAll)responseType(typenewDataStore.class)publicnewDataStoremytimerselectAll()throwsutilException{mytimer daonewmytimer();dao.setSearchMethod(selectAll);Listmytimerlist(Listmytimer)dao.search();newRowSetmytimerrowsetnewnewRowSet();rowset.setPrimary(list);newDataStoremytimerdsnewnewDataStore();ds.setName(all);ds.setRowset(rowset);returnds;}// 2. 保存/更新任务配置LoggerTransresponseMapping(key/save)responseType(typeString.class)publicStringsave(newDataStoremytimerds)throwsutilException{ds.save();return保存成功修改后重启调度即可生效;}// 3. 查询单个任务详情LoggerTransmonitoringresponseMapping(key/searchOne)responseType(typenewDataStore.class)publicnewDataStoremytimerselectOne(mytimer dao)throwsutilException{dao.setSearchMethod(selectByPrimaryKey);Listmytimerlist(Listmytimer)dao.search();newRowSetmytimerrowsetnewnewRowSet();rowset.setPrimary(list);newDataStoremytimerdsnewnewDataStore();ds.setName(one);ds.setRowset(rowset);returnds;}// 4. 启动所有启用状态的定时任务核心TransmonitoringresponseMapping(key/start)publicvoidstart()throwsutilException{TimertimerTimeListener.getTimer();log.info(newDate() 定时器已启动);mytimer daonewmytimer();dao.setSearchMethod(selectAll);try{Listmytimerlist(Listmytimer)dao.search();for(mytimer task:list){// 只加载启用状态的任务if(task.getStatus()0){continue;}// 周期秒 → 毫秒longperiodtask.getPeriod()*1000L;DatefirstTimetask.getBegintime();DatenownewDate();// 未设置首次时间默认当前时间if(firstTimenull){firstTimenow;}// 首次时间已过自动计算下一次执行时间周期对齐if(firstTime.before(now)){longdelay(now.getTime()-firstTime.getTime())%period;firstTimenewDate(now.getTime()period-delay);}StringclassNametask.getClassname();try{// 反射实例化任务注册到TimerTimerTasktimerTask(TimerTask)Class.forName(className).newInstance();timer.schedule(timerTask,firstTime,period);log.info(任务注册成功className首次执行firstTime);}catch(Exceptione){log.error(任务注册失败className,e);}}}catch(Exceptione){log.error(定时器启动异常,e);}}// 5. 停止所有定时任务monitoringresponseMapping(key/stop)publicvoidstop(){TimeListener.cancel();log.info(newDate() 定时器已停止);}}2. 任务类编写规范极简所有业务任务只需继承TimerTask实现run()方法即可/** * 数据同步定时任务 */publicclassSyncDataTaskextendsTimerTask{Overridepublicvoidrun(){try{// 业务逻辑数据同步、报表生成、清理日志等System.out.println(定时同步数据执行newDate());}catch(Exceptione){log.error(SyncDataTask执行异常,e);}}}3. 全局Timer生命周期管理通过ServletContextListener监听Web容器生命周期保证Timer单例、安全销毁publicclassTimeListenerimplementsServletContextListener{privatestaticTimertimer;OverridepublicvoidcontextInitialized(ServletContextEventsce){// 全局单例Timer后台守护线程执行timernewTimer(browise-timer,true);}OverridepublicvoidcontextDestroyed(ServletContextEventsce){// 容器关闭时取消所有任务释放线程if(timer!null){timer.cancel();}}publicstaticTimergetTimer(){returntimer;}publicstaticvoidcancel(){if(timer!null){timer.cancel();}}}五、关键设计亮点必看1. 反射动态加载数据库存储类全限定名运行时用Class.forName()加载类、newInstance()创建实例无需硬编码新增任务只需要写类、配数据库即可。2. 智能首次执行时间如果配置的首次时间早于当前时间不立即执行而是按周期对齐到下一个时间点例如配置凌晨2点当前15:00则自动改为次日凌晨2点执行避免重复执行。3. 全局单例Timer所有任务共用一个Timer减少线程资源消耗通过监听器管理生命周期防止内存泄漏。4. 页面化运维提供标准CRUD接口可快速对接前端页面/timer/searchAll查看所有任务/timer/save新增/修改任务/timer/start启动调度/timer/stop停止调度5. 框架能力集成结合自研框架注解自动获得Trans事务管理Logger操作日志monitoring性能监控aoppointAOP增强六、方案优缺点? 优点零依赖纯JDK实现不引入Quartz等第三方包轻量简洁核心代码仅150行易读易维护动态生效配置存数据库页面修改无需重启服务适配政务场景固定周期执行满足90%政务定时需求稳定可靠JDK原生Timer经过长期生产环境验证。?? 局限不支持Cron表达式单Timer线程任务执行阻塞会影响后续任务可优化为ScheduledExecutorService无分布式调度能力单机场景够用。七、适用场景政务内网、金融内网等无外网、依赖管控严格的环境小型/中型项目固定周期执行的简单定时任务追求轻量、稳定、易运维不想引入重框架的场景。八、总结本方案用Timer 反射 数据库表以极小的代码量实现了企业级定时任务调度完全替代Quartz满足政务系统常规需求。无依赖、易部署、可视化运维在生产环境稳定运行多年是轻量化定时任务的优选方案。政务项目里定时任务大家用的什么方案欢迎评论区交流标签#Java #定时任务 #Timer #反射 #数据库驱动 #政务信息化 #自研框架 #轻量调度

更多文章