背景
在使用XXL—JOB的实现定时任务过程中,有时候可能由于部署环境的要求,就只能用Spring自带的实现方式。
所以为了通用性和灵活性,突发奇想地看看能不能实现在不修改原本Spring定时任务代码的前提下,通过配置灵活控制定时任务具体的实现,同时任务的日志的管理也要同步进行切换。
分析并列出需要解决的问题思路
根据需求背景可以初步分析实现的大致方向和实现流程。实现的思路其实不复杂,重点在于如何具体去实现落地。

具体实现
判断是否启用XXl-JOB的实现方式
和大多数第三方starter包一样,我们可以利用SpringBoot的自动装配,读取配置中的某个属性值,作为是否装配我们写的类。特别注意的是SpringBoot不同版本的配置方式有所不同。
自动装配类如下:
._________/\/___'_____(_)______\\(()___|'_|'_||'_/_`|\\\/___)||_)|||||||(_||))))'|____|.__|_||_|_||___,|////=========|_|==============|___/=/_/_/_/::SpringBoot::(v3.0.5)2023-05-0715:56:50.011[main]INFOcom.teoan.job.auto.samples.XxlJobAutoApplication-StartingXxlJobAutoApplicationusingJava17.0.6withPID30937(/Users/teoan/Project/xxl-job-auto/xxl-job-auto-spring-boot-samples/target/classesstartedbyteoanin/Users/teoan/Project/xxl-job-auto)2023-05-0715:56:50.025[main]INFOcom.teoan.job.auto.samples.XxlJobAutoApplication-Noactiveprofileset,fallingbackto1defaultprofile:"default"2023-05-0715:56:51.538[main]INFOo.s.boot.web.embedded.tomcat.TomcatWebServer-Tomcatinitializedwithport(s):8080(http)2023-05-0715:56:51.548[main]INFOorg.apache.coyote.http11.Http11NioProtocol-InitializingProtocolHandler["http-nio-8080"]2023-05-0715:56:51.549[main]INFOorg.apache.catalina.core.StandardService-Startingservice[Tomcat]2023-05-0715:56:51.549[main]INFOorg.apache.catalina.core.StandardEngine-StartingServletengine:[ApacheTomcat/10.1.7]2023-05-0715:56:51.642[main]INFOo.a.c.core.ContainerBase.[Tomcat].[localhost].[/]-InitializingSpringembeddedWebApplicationContext2023-05-0715:56:51.642[main]INFOo.s.b.w.s.c.ServletWebServerApplicationContext-RootWebApplicationContext:initializationcompletedin1351ms2023-05-0715:56:51.835[main]INFOcom.teoan.job.auto.samples.config.XxlJobConfig->>>>>>>>>>>xxl-jobconfiginit.2023-05-0715:56:52.282[main]INFOo.s.b.actuate.endpoint.web.EndpointLinksResolver-Exposing1endpoint(s)beneathbasepath'/actuator'2023-05-0715:56:52.444[main]INFOorg.apache.coyote.http11.Http11NioProtocol-StartingProtocolHandler["http-nio-8080"]2023-05-0715:56:52.457[main]INFOo.s.boot.web.embedded.tomcat.TomcatWebServer-Tomcatstartedonport(s):8080(http)withcontextpath''2023-05-0715:56:52.477[scheduling-1]INFOc.teoan.job.auto.samples.job.XxlJobAutoSamplesJob-samplesJobexecutorsuccess!2023-05-0715:56:52.480[main]INFOcom.teoan.job.auto.samples.XxlJobAutoApplication-StartedXxlJobAutoApplicationin3.118seconds(processrunningfor3.86)2023-05-0715:56:52.515[Thread-4]INFOcom.xxl.job.core.server.EmbedServer->>>>>>>>>>>xxl-jobremotingserverstartsuccess,nettype=classcom.xxl.job.core.server.EmbedServer,port=99992023-05-0715:56:52.712[RMITCPConnection(3)-192.168.123.139]INFOo.a.c.core.ContainerBase.[Tomcat].[localhost].[/]-InitializingSpringDispatcherServlet'dispatcherServlet'2023-05-0715:56:52.714[RMITCPConnection(3)-192.168.123.139]INFOorg.springframework.web.servlet.DispatcherServlet-InitializingServlet'dispatcherServlet'2023-05-0715:56:52.715[RMITCPConnection(3)-192.168.123.139]INFOorg.springframework.web.servlet.DispatcherServlet-Completedinitializationin1ms2023-05-0715:56:53.145[main]INFOcom.teoan.job.auto.core.JobAutoRegister->>>>>>>>>>>xxl-jobautoregistergroupsuccess!2023-05-0715:56:53.490[main]INFOcom.xxl.job.core.executor.XxlJobExecutor->>>>>>>>>>>xxl-jobregisterjobhandlersuccess,name:com.teoan.job.auto.samples.job.XxlJobAutoSamplesJob#samplesJob,jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@223cbf0d[classcom.teoan.job.auto.samples.job.XxlJobAutoSamplesJob#samplesJob]2023-05-0715:56:53.647[main]INFOcom.teoan.job.auto.core.JobAutoRegister->>>>>>>>>>>xxl-jobautoaddjobInfosuccess!JobInfoId[11085]JobInfo[{"id":0,"jobGroup":2080,"jobDesc":"com.teoan.job.auto.samples.job.XxlJobAutoSamplesJob#samplesJob","author":"JobAutoRegister","scheduleType":"FIX_RATE","scheduleConf":"10","misfireStrategy":"DO_NOTHING","executorRouteStrategy":"FIRST","executorHandler":"com.teoan.job.auto.samples.job.XxlJobAutoSamplesJob#samplesJob","executorBlockStrategy":"SERIAL_EXECUTION","executorTimeout":0,"executorFailRetryCount":0,"glueType":"BEAN","glueRemark":"GLUE代码初始化","triggerStatus":1,"triggerLastTime":0,"triggerNextTime":0}]2023-05-0715:56:53.650[main]INFOcom.teoan.job.auto.core.JobAutoRegister->>>>>>>>>>>xxl-jobautoregistersuccess2023-05-0715:57:24.538[xxl-job,EmbedServerbizThreadPool-123827075]INFOcom.xxl.job.core.executor.XxlJobExecutor->>>>>>>>>>>xxl-jobregistJobThreadsuccess,jobId:11085,handler:com.xxl.job.core.handler.impl.MethodJobHandler@223cbf0d[classcom.teoan.job.auto.samples.job.XxlJobAutoSamplesJob#samplesJob]2023-05-0715:57:24.540[xxl-job,JobThread-11085-1683446244537]INFOc.teoan.job.auto.samples.job.XxlJobAutoSamplesJob-samplesJobexecutorsuccess!
日志看起来没啥问题,注册执行器和注册任务信息的相关日志都打印了出来,定时任务的执行日志也有了。我们上调度中心看看。



嗯,符合预期,执行器和任务详情都自动添加到调度中心了,任务中心的日志也能在调度中心中查看了。
实现过程中思考的几个问题
是否实现任务信息的更新
一开始想着是否需要监听注解上值的变化,对应地去更新XXL-JOB上的任务信息,如经常需要改变的定时任务的间隙时间或者corn表达式,后来还是决定不实现了,考虑到大多数场景下,自动注册任务只是作为应用启动的初始化工作,后续需要调整还是得上调度中心进行操作,所以任务的配置就不能一直以注解上配置为准了。
是否采用修改数据库数据的方式实现任务的注册
自动注册任务和执行器信息,其实可以直接利用ORM操作数据库去实现。不过如果XXL-JOB的数据库和当前应用不在同一台机器上,就需要配置多个数据源了,相对比较麻烦,对于第三方使用者来说,也会多出一些配置。总体看起来不够优雅,最后还是采用读取调度中心地址,利用http工具调用API的方式去实现。
是否在自动装配类上加上@Scheduled
在提供的自动装配类中,其实可以帮使用者默认加上 @Scheduled 开启SpringBoot的自动任务,但是为了尽量不影响正常的开发配置,开头说到的尽量让用户无感知,所以这个 @Scheduled 还是需要starter的使用方自己去配置,然后走默认实现的定时任务开发。
提供的Starter是否加上XXL-Job的依赖
提供的strarter包只是作为增强功能的存在,所以是可选的,不应该耦合XXL-JOB的核心依赖,就像Hutool中POI工具一样,本身并不依赖POI的核心依赖,作为Strarter包,应该只提供自己的核心功能就行。
总结
第一次根据自己的突发奇想,对中间件进行二次开发,了解了XXL-JOB的具体实现的过程中,也间接锻炼了自己阅读开源代码的能力。 从有想法到实现,这个过程中自己收获颇多,也就有了这篇博客,当作自己的过程笔记吧,分享给有需要的人。源码什么的也在github上开源了,喜欢的小伙伴也不妨点个stars。
项目地址
https://github.com/Teoan/xxl-job-auto
来源:juejin.cn/post/7247810665241755703
构建高质量的技术交流社群,欢迎从事编程开发、技术招聘HR进群,也欢迎大家分享自己公司的内推信息,相互帮助,一起进步!
文明发言,以
交流技术、职位内推、行业探讨为主
广告人士勿入,切勿轻信私聊,防止被骗

加我好友,拉你进群

本篇文章来源于微信公众号: Java面试题精选
微信扫描下方的二维码阅读本文

Comments NOTHING