城市直播房产教育博客汽车
投稿投诉
汽车报价
买车新车
博客专栏
专题精品
教育留学
高考读书
房产家居
彩票视频
直播黑猫
投资微博
城市上海
政务旅游

SpringBootQuartz实现动态定时任务(非数据库模

6月22日 断龙塔投稿
  在日常工作中,经常会遇到一些定时任务,比如定时发邮件、异构数据库同步数据等。目前比较常用的是SpringBootQuartz实现动态定时任务的Web项目,这种模式通常需要建立定时任务相关的表。本例为SpringBootQuartz实现动态定时任务的非Web项目,可以根据项目启动的参数来决定执行配置文件中的某些任务,并且所有的任务都配置在配置文件中,从而避免建数据库的麻烦。
  一、流程说明:
  程序启动时注册QuartzConfig配置类(该配置类将读取quartz。properties中的配置、任务信息、初始化调度器、job实例工厂等),然后通过CommandLineRunner的实现类,重写其run()方法,该方法根据启动传入的参数判断哪些配置任务信息需要进行执行,并调用QuartzManager工具类启动相应任务。
  二、代码实例:
  1。引入相关依赖dependenciesdependencygroupIdorg。springframework。bootgroupIdspringbootstarterartifactIddependency!quartz动态定时任务dependencygroupIdorg。springframework。bootgroupIdspringbootstarterquartzartifactIddependency!导入lombok组件简化代码dependencygroupIdorg。projectlombokgroupIdlombokartifactIdscopeprovidedscope!只在编译阶段生效,不需要打入包中dependency!导入常用辅助工具类dependencygroupIdcn。hutoolgroupIdhutoolallartifactIdversion5。1。0versiondependency!测试dependencygroupIdorg。springframework。bootgroupIdspringbootstartertestartifactIdscopetestscopedependencydependencies!将项目打包成可执行jar包buildpluginsplugingroupIdorg。springframework。bootgroupIdspringbootmavenpluginartifactId!如果没有配置fork属性,热部署不会起效configurationforktrueforkconfigurationpluginpluginsbuild
  2。【必须】quartz框架配置文件quartz。properties,主要配置quartz线程池、任务列表等
  说明:由于本例采用非Web项目,故application。yml配置文件可以不配。实际业务中可以配置些动态数据源,实现定时任务的业务逻辑〔非必须〕设置调度器实例名称,默认QuartzSchedulerorg。quartz。scheduler。instanceNamequartzscheduler〔非必须〕设置调度器实例ID,默认值NONCLUSTEREDorg。quartz。scheduler。instanceIdAUTO〔必须〕设置线程池实现类(一般使用SimpleThreadPool定长线程池)org。quartz。threadPool。classorg。quartz。simpl。SimpleThreadPool〔必须〕设置线程数(无默认值,一般设置为1100的整数)org。quartz。threadPool。threadCount5〔非必须〕设置线程的优先级(最大为9,最小为1,默认为5)org。quartz。threadPool。threadPriority5〔非必须〕设置是否为守护线程(默认为true)org。quartz。threadPool。threadsInheritContextClassLoaderOfInitializingThreadtrue〔非必须〕线程前缀(默认为调度器实例名称Worker)org。quartz。threadPool。threadNamePrefixquartzschedulerthread〔非必须〕设置schedule相关信息存储方法(默认存储在内存中)org。quartz。jobStore。classorg。quartz。simpl。RAMJobStore〔非必须〕最大能忍受的触发超时时间(默认为60秒)org。quartz。jobStore。misfireThreshold60000配置定时任务jobName:任务名称,建议英文或任务描述拼音码首拼〔必须〕jobDesc:任务中文描述〔必须〕classMethod:任务执行的方法〔必须〕jobCron:任务的Cron表达式〔必须〕第1个定时任务springboot。quartz。scheduledJobs〔0〕。jobNamejob1springboot。quartz。scheduledJobs〔0〕。jobDesc测试任务1springboot。quartz。scheduledJobs〔0〕。classMethodcom。wwu。jobs。FirstJobspringboot。quartz。scheduledJobs〔0〕。jobCron010?第2个定时任务springboot。quartz。scheduledJobs〔1〕。jobNamejob2springboot。quartz。scheduledJobs〔1〕。jobDesc测试任务2springboot。quartz。scheduledJobs〔1〕。classMethodcom。wwu。jobs。SecondJobspringboot。quartz。scheduledJobs〔1〕。jobCron015?第3个定时任务springboot。quartz。scheduledJobs〔2〕。jobNamejob3springboot。quartz。scheduledJobs〔2〕。jobDesc测试任务3springboot。quartz。scheduledJobs〔2〕。classMethodcom。wwu。jobs。ThirdJobspringboot。quartz。scheduledJobs〔2〕。jobCron00519?2
  3。【非必须】slf4j日志分级切割配置文件logbackspring。?xmlversion1。0encodingUTF8?!scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。scanPeriod:设置监测配置文件是否有修改的时间间隔,默认的时间间隔为1分钟,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。debug:当此属性设置为true时,将打印出logback内部ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a信息,实时查看logback运行状态。默认值为false。configurationscanfalsescanPeriod60secondsdebugfalse!property标签用来定义变量值的标签,有两个属性变量名称name和变量值可以使{}来使用变量!定义ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a的根目录:在项目所在盘符的根目录下创建logs文件夹propertynamesysLog。logDirvalue。logs!定义ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a文件名称propertynamesysLog。logNamevaluesystem!保留最近n天的归档ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志apropertynamesysLog。maxHistoryvalue7!每个文件的大小propertynamesysLog。maxFileSizevalue50MB!异步缓冲队列的深度,该值会影响性能。默认值为256propertynamesysLog。queueSizevalue512!输出ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a文件编码propertynamesysLog。fileCharsetvalueUTF8!输出ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a文件格式propertynamesysLog。patternvalued{yyyyMMddHH:mm:ss。SSS}〔thread〕〔5level〕〔logger{50}:line〕msgn!控制台策略打印ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a的相关配置!ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a格式encoderpattern{sysLog。pattern}patternencoderappender!文件输出策略打印ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a的相关配置!切分Info级别ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a!过滤INFO级别ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志afilterclassch。qos。logback。classic。filter。LevelFilter!过滤INFOlevelINFOlevel!匹配到就输出onMatchACCEPTonMatch!没有匹配就禁止onMismatchDENYonMismatchfilter!该属性存在则表示当天的ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a路径及名称,若不存在则使用FileNamePattern属性之作为当天的ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a路径及名称如果同时有File和FileNamePattern则明天会自动把今天的ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a改名为今天的日期。file{sysLog。logDir}{sysLog。logName}info。txtfile!滚动策略,按照时间滚动TimeBasedRollingPolicyrollingPolicyclassch。qos。logback。core。rolling。TimeBasedRollingPolicy!滚动时产生的文件的存放位置及文件名称d{yyyyMMdd}:按天进行ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a滚动i:当文件大小超过maxFileSize时,按照i进行文件滚动fileNamePattern{sysLog。logDir}{sysLog。logName}infod{yyyyMMdd}i。txtfileNamePattern!只保留最近7天的ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a,超出数量就删除旧文件及为归档而创建的目录MaxHistory{sysLog。maxHistory}MaxHistory!当ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a文件超过maxFileSize指定的大小是,根据上面提到的i进行ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a文件滚动此处必须配置timeBasedFileNamingAndTriggeringPolicy,否则无法实现按文件大小进行滚动。timeBasedFileNamingAndTriggeringPolicyclassch。qos。logback。core。rolling。SizeAndTimeBasedFNATPmaxFileSize{sysLog。maxFileSize}maxFileSizetimeBasedFileNamingAndTriggeringPolicyrollingPolicy!ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a输出格式:encodercharset{sysLog。fileCharset}charsetpattern{sysLog。pattern}patternencoderappender!切分WARN级别以上ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a!过滤WARN级别以上ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志afilterclassch。qos。logback。classic。filter。ThresholdFilter!过滤ERRORlevelWARNlevelfilter!该属性存在则表示当天的ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a路径及名称,若不存在则使用FileNamePattern属性之作为当天的ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a路径及名称如果同时有File和FileNamePattern则明天会自动把今天的ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a改名为今天的日期。file{sysLog。logDir}{sysLog。logName}error。txtfile!滚动策略,按照时间滚动TimeBasedRollingPolicyrollingPolicyclassch。qos。logback。core。rolling。TimeBasedRollingPolicy!滚动时产生的文件的存放位置及文件名称d{yyyyMMdd}:按天进行ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a滚动i:当文件大小超过maxFileSize时,按照i进行文件滚动fileNamePattern{sysLog。logDir}{sysLog。logName}errord{yyyyMMdd}i。txtfileNamePattern!只保留最近7天的ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a,超出数量就删除旧文件及为归档而创建的目录MaxHistory{maxHistory}MaxHistory!当ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a文件超过maxFileSize指定的大小是,根据上面提到的i进行ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a文件滚动此处必须配置timeBasedFileNamingAndTriggeringPolicy,否则无法实现按文件大小进行滚动。timeBasedFileNamingAndTriggeringPolicyclassch。qos。logback。core。rolling。SizeAndTimeBasedFNATPmaxFileSize{sysLog。maxFileSize}maxFileSizetimeBasedFileNamingAndTriggeringPolicyrollingPolicy!ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a输出格式:encodercharset{sysLog。fileCharset}charsetpattern{sysLog。pattern}patternencoderappender!异步ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a记录配置!不丢失ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a。默认的,如果队列的80已满,则会丢弃TRACT、DEBUG、INFO级别的ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志adiscardingThreshold0discardingThreshold!更改默认的队列的深度,该值会影响性能。默认值为256queueSize{sysLog。queueSize}queueSizeappenderdiscardingThreshold0discardingThresholdqueueSize{sysLog。queueSize}queueSizeappender!下面配置一些第三方包的ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a过滤级别,用于避免刷屏loggernameorg。springframeworklevelWARNloggernameorg。thymeleaflevelWARNloggernameorg。apachelevelWARN!ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a输出级别rootlevelINFOroot!!测试环境和开发环境ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a输出级别为debug!springProfilenametest,dev!rootlevelDEBUG!!rootlevelDEBUG!!!!root!springProfile!!生产环境ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a输出级别为info!springProfilenameprod!rootlevelINFO!!!!root!springProfileconfiguration
  4。创建任务实体类ScheduledJob。java,在初始化任务列表时创建任务明细(JobDetail)及触发器(Trigger)packagecom。wwu。importlombok。Ddescription:任务实体类author一蓑烟雨version1。0。0date2023041616:53DatapublicclassScheduledJob{任务IDprivateStringjobId;任务名称privateStringjobN任务描述privateStringjobD任务表达式privateStringjobC任务表达式中文privateStringjobCronZh;任务分组编码privateStringjobG任务分组名称privateStringjobGroupN执行方法privateStringclassM任务执行状态(Y,执行成功;N,执行失败;空,未执行)privateStringjobS任务可用状态(Y:可用;N:不可用)privateStringenabledF下次执行时间privateStringnextExecT}
  5。创建quartz配置类quartzConfig。java,主要用来配置线程池、调度器、job实例工厂等packagecom。wwu。importcom。wwu。entity。ScheduledJimportlombok。Dimportorg。quartz。Simportorg。quartz。spi。JobFimportorg。springframework。beans。factory。config。PropertiesFactoryBimportorg。springframework。boot。context。properties。ConfigurationPimportorg。springframework。context。annotation。Bimportorg。springframework。context。annotation。Cimportorg。springframework。context。annotation。PropertySimportorg。springframework。core。io。ClassPathRimportorg。springframework。scheduling。quartz。SchedulerFactoryBimportjavax。annotation。Rimportjava。io。IOEimportjava。util。Limportjava。util。Pdescription:quartz配置类,配置线程池、调度器、job实例工厂等author一蓑烟雨version1。0。0date2023041618:08DataConfigurationPropertySource(classpath:quartz。properties)ConfigurationProperties(prefixspringboot。quartz)publicclassQuartzConfig{注入quartz。properties配置文件中的任务privateListScheduledJobscheduledJResourceprivateJobFactoryjobFdescription:SchedulerFactoryBean工厂returnorg。springframework。scheduling。quartz。SchedulerFactoryBeanauthor一蓑烟雨date202341618:10BeanpublicSchedulerFactoryBeanschedulerFactoryBean(){创建SchedulerFactoryBean实例SchedulerFactoryBeanschedulerFactoryBeannewSchedulerFactoryBean();try{设置是否覆盖已存在的job,为True表示有相同名称和分组的触发器和任务存在时则替换schedulerFactoryBean。setOverwriteExistingJobs(true);设置是否自动启动SchedulerschedulerFactoryBean。setAutoStartup(true);设置quartz属性schedulerFactoryBean。setQuartzProperties(quartzProperties());设置任务调度器schedulerFactoryBean。setJobFactory(jobFactory);}catch(Exceptione){e。printStackTrace();}returnschedulerFactoryB}description:读取quartz配置文件中配置相关属性returnjava。util。Propertiesauthor一蓑烟雨date202341717:18BeanpublicPropertiesquartzProperties()throwsIOException{PropertiesFactoryBeanpropertiesFactoryBeannewPropertiesFactoryBean();propertiesFactoryBean。setLocation(newClassPathResource(quartz。properties));在quartz。properties中的属性被读取并注入后再初始化对象propertiesFactoryBean。afterPropertiesSet();returnpropertiesFactoryBean。getObject();}description:初始化schedule任务调度器returnorg。quartz。Schedulerauthor一蓑烟雨date202341618:12BeanpublicSchedulerscheduler(){returnschedulerFactoryBean()。getScheduler();}}
  6。创建job实例工厂JobFactory。javapackagecom。wwu。importorg。quartz。spi。TriggerFiredBimportorg。springframework。beans。factory。config。AutowireCapableBeanFimportorg。springframework。scheduling。quartz。AdaptableJobFimportorg。springframework。stereotype。Cimportjavax。annotation。Rdescription:创建job实例工厂author一蓑烟雨version1。0。0date2023041618:31ComponentpublicclassJobFactoryextendsAdaptableJobFactory{ResourceprivateAutowireCapableBeanFactorycapableBeanFOverrideprotectedObjectcreateJobInstance(TriggerFiredBundlebundle)throwsException{调用父类的方法ObjectjobInstancesuper。createJobInstance(bundle);进行注入capableBeanFactory。autowireBean(jobInstance);returnjobI}}
  7。创建CommandLineRunner接口的实现类QuartzCommandRunner。java,作用为启动项目时预先加载配置文件中的所有定时任务,并根据启动参数启动相应任务packagecom。wwu。importcom。wwu。entity。ScheduledJimportlombok。extern。slf4j。Slf4j;importorg。quartz。SchedulerEimportorg。springframework。boot。CommandLineRimportorg。springframework。core。annotation。Oimportorg。springframework。stereotype。Cimportjavax。annotation。Rimportjava。util。ArrayLimportjava。util。Aimportjava。util。Ldescription:启动项目时预先加载配置文件中的所有定时任务,并根据启动参数启动相应任务CommandLineRunner中的Order表示在项目启动时预先加载的类author一蓑烟雨version1。0。0date2023041618:13Slf4jComponentOrder(1)publicclassQuartzCommandRunnerimplementsCommandLineRunner{ResourceprivateQuartzManagerquartzMResourceprivateQuartzConfigquartzCdescription:重写run方法param〔args〕returnvoidauthor一蓑烟雨date202341715:37Overridepublicvoidrun(String。。。args)throwsException{try{初始化需要启动的任务列表ListScheduledJobjobListinitSchedule(args);for(ScheduledJobscheduledJob:jobList){执行任务quartzManager。startJob(scheduledJob);}}catch(Exceptione){e。printStackTrace();}}description:初始化需要执行的任务列表param〔args〕returnjava。util。Listcom。wwu。entity。ScheduledJobauthor一蓑烟雨date202341715:37publicListScheduledJobinitSchedule(String。。。args)throwsSchedulerException{ListScheduledJobjobsnewArrayListScheduledJob();try{log。info(。。。根据参数加载配置文件quartz。properties中任务列表开始。。。);1。遍历启动程序时传入的接口类型参数String〔〕typePfor(Stringarg:args){if(arg。startsWith(type)){typeParamarg。substring(5)。split(,);}}2。遍历quartz。properties配置文件中任务列表for(ScheduledJobscheduledJob:quartzConfig。getScheduledJobs()){如果启动传入了参数,则按照参数加载启动任务if(typeParam!nulltypeParam。length0){遍历参数值和任务列表,若相同则加入到启动任务列表中Arrays。stream(typeParam)。forEach(param{if(param。trim()。equals(scheduledJob。getJobName())){jobs。add(scheduledJob);log。info(。。。。。。scheduledJob);}});}else{没有启动参数,默认启动配置文件中的所有任务jobs。add(scheduledJob);log。info(。。。。。。scheduledJob);}}log。info(。。。。。。共加载{}条任务需要执行。。。。。。,jobs。size());}catch(Exceptione){e。printStackTrace();}log。info(。。。根据参数加载配置文件quartz。properties中任务列表结束。。。);}}
  8。创建quartz定时任务工具类QuartzManager。java,对任务进行管理(创建、启动、修改、删除、暂停)packagecom。wwu。importcom。wwu。entity。ScheduledJimportorg。quartz。;importorg。quartz。impl。matchers。GroupMimportorg。springframework。stereotype。Cimportjavax。annotation。Rimportjava。util。ArrayLimportjava。util。Limportjava。util。Sdescription:quartz定时任务工具类,对任务进行管理(创建、启动、修改、删除、暂停)author一蓑烟雨version1。0。0date2023041617:11ComponentpublicclassQuartzManager{注入QuartzConfig中定义的任务调度器schedulerResourceprivateSdescription:获取所有任务信息returnjava。util。Listcom。wwu。entity。ScheduledJobauthor一蓑烟雨date202341618:59publicListScheduledJobgetAllJobInfo()throwsSchedulerException{ListScheduledJobjobListnewArrayListScheduledJob();GroupMatcherJobKeymatcherGroupMatcher。anyJobGroup();SetJobKeyjobKeysscheduler。getJobKeys(matcher);for(JobKeyjobKey:jobKeys){L?extendsTriggertriggersscheduler。getTriggersOfJob(jobKey);for(Triggertrigger:triggers){ScheduledJobjobnewScheduledJob();job。setJobName(jobKey。getName());job。setJobGroup(jobKey。getGroup());job。setJobDesc(trigger。getDescription());Trigger。TriggerStatetriggerStatescheduler。getTriggerState(trigger。getKey());job。setJobStatus(triggerState。name());if(triggerinstanceofCronTrigger){CronTriggercronTrigger(CronTrigger)job。setJobCron(cronTrigger。getCronExpression());}jobList。add(job);}}returnjobL}description:获取某个任务的信息paramscheduledJobreturnjava。lang。Stringauthor一蓑烟雨date202341618:07publicStringgetJobInfo(ScheduledJobscheduledJob)throwsSchedulerException{TriggerKeytriggerKeynewTriggerKey(scheduledJob。getJobName(),scheduledJob。getJobGroup());System。out。println(triggerKey:triggerKey);CronTriggercronTrigger(CronTrigger)scheduler。getTrigger(triggerKey);returnString。format(time:s,state:s,cronTrigger。getCronExpression(),scheduler。getTriggerState(triggerKey)。name());}description:获取任务数量returnjava。lang。Stringauthor一蓑烟雨date202341618:07publicintgetJobSize()throwsSchedulerException{GroupMatcherJobKeymatcherGroupMatcher。anyJobGroup();SetJobKeyjobKeysscheduler。getJobKeys(matcher);returnjobKeys。size();}description:获取触发器状态paramscheduledJobreturnNONE:不存在;NORMAL:正常;PAUSED:暂停;COMPLETE:完成;ERROR:错误;BLOCKED:阻塞author一蓑烟雨date202341718:56publicStringgetTriggerState(ScheduledJobscheduledJob)throwsSchedulerException{TriggerKeytriggerKeynewTriggerKey(scheduledJob。getJobName(),scheduledJob。getJobGroup());Trigger。TriggerStatetriggerStatescheduler。getTriggerState(triggerKey);returntriggerState。name();}description:开启某个任务paramscheduledJobreturnvoidauthor一蓑烟雨date202341618:05publicvoidstartJob(ScheduledJobscheduledJob)throwsException{JobKeyjobKeyJobKey。jobKey(scheduledJob。getJobName(),scheduledJob。getJobGroup());不存在则添加任务if(!scheduler。checkExists(jobKey)){addJobTask(scheduledJob);}启动scheduler。start();}description:添加某个任务paramscheduledJobreturnvoidauthor一蓑烟雨date202341618:01publicbooleanaddJobTask(ScheduledJobscheduledJob)throwsException{利用反射机制获取任务执行类C?extendsJobjobClass(C?extendsJob)(Class。forName(scheduledJob。getClassMethod())。newInstance()。getClass());设置任务明细,调用定义的任务逻辑JobDetailjobDetailJobBuilder。newJob(jobClass)添加认证信息(也可通过usingJobData传参数)。withIdentity(scheduledJob。getJobName(),scheduledJob。getJobGroup())执行。build();设置任务触发器,cornTrigger规则定义执行规则CronTriggercronTriggerTriggerBuilder。newTrigger()通过键值对方式向job实现业务逻辑传参数。usingJobData(jobDesc,scheduledJob。getJobDesc())。usingJobData(jobCron,scheduledJob。getJobCron())添加认证信息。withIdentity(scheduledJob。getJobName(),scheduledJob。getJobGroup())程序启动后间隔多久开始执行任务。startAt(DateBuilder。futureDate(5,DateBuilder。IntervalUnit。SECOND))执行Cron表达时。withSchedule(CronScheduleBuilder。cronSchedule(scheduledJob。getJobCron()))执行。build();把任务明细和触发器注册到任务调度中scheduler。scheduleJob(jobDetail,cronTrigger);}description:修改任务的Cron表达式paramscheduledJobreturnbooleanauthor一蓑烟雨date202341617:46publicbooleanmodifyJob(ScheduledJobscheduledJob)throwsSchedulerException{TriggerKeytriggerKeynewTriggerKey(scheduledJob。getJobName(),scheduledJob。getJobGroup());CronTriggercronTrigger(CronTrigger)scheduler。getTrigger(triggerKey);StringoldTimecronTrigger。getCronExpression();if(!oldTime。equalsIgnoreCase(scheduledJob。getJobCron())){CronScheduleBuildercronScheduleBuilderCronScheduleBuilder。cronSchedule(scheduledJob。getJobCron());CronTriggertriggerTriggerBuilder。newTrigger()。withIdentity(scheduledJob。getJobName(),scheduledJob。getJobGroup())。withSchedule(cronScheduleBuilder)。build();scheduler。rescheduleJob(triggerKey,trigger);}else{}}description:暂停所有任务returnvoidauthor一蓑烟雨date202341617:41publicvoidpauseAllJob()throwsSchedulerException{scheduler。pauseAll();}description:暂停某个任务paramscheduledJobreturnvoidauthor一蓑烟雨date202341617:41publicvoidpauseJob(ScheduledJobscheduledJob)throwsSchedulerException{JobKeyjobKeyJobKey。jobKey(scheduledJob。getJobName(),scheduledJob。getJobGroup());JobDetailjobDetailscheduler。getJobDetail(jobKey);if(jobDetailnull){}scheduler。pauseJob(jobKey);}description:恢复所有任务returnvoidauthor一蓑烟雨date202341617:38publicvoidresumeAllJob()throwsSchedulerException{scheduler。resumeAll();}description:恢复某个任务paramscheduledJobreturnvoidauthor一蓑烟雨date202341617:39publicvoidresumeJob(ScheduledJobscheduledJob)throwsSchedulerException{JobKeyjobKeyJobKey。jobKey(scheduledJob。getJobName(),scheduledJob。getJobGroup());JobDetailjobDetailscheduler。getJobDetail(jobKey);if(jobDetailnull){}scheduler。resumeJob(jobKey);}description:删除任务paramscheduledJobreturnvoidauthor一蓑烟雨date202341617:32publicvoiddeleteJob(ScheduledJobscheduledJob)throwsSchedulerException{JobKeyjobKeyJobKey。jobKey(scheduledJob。getJobName(),scheduledJob。getJobGroup());JobDetailjobDetailscheduler。getJobDetail(jobKey);if(jobDetailnull){}scheduler。deleteJob(jobKey);}}
  8。依次创建quartz中对应任务的job业务类FirstJob。java、SecondJob。java和ThirdJob。java,这些job业务类需要实现Job接口packagecom。wwu。importlombok。extern。slf4j。Slf4j;importorg。quartz。;description:定义任务逻辑,需要实现Job接口并重写execute()方法DisallowConcurrentExecution注解用来避免同一个任务由于执行时间过长导致并发执行author一蓑烟雨version1。0。0date2023041619:51Slf4jDisallowConcurrentExecutionpublicclassFirstJobimplementsJob{Overridepublicvoidexecute(JobExecutionContextcontext)throwsJobExecutionException{获取触发器cronTrigger传递的参数JobDataMapdataMapcontext。getTrigger()。getJobDataMap();log。info(【{}】任务执行开始,执行频率为:{},dataMap。get(jobDesc),dataMap。get(jobCron));try{Thread。sleep(30000);}catch(InterruptedExceptione){e。printStackTrace();}log。info(【{}】任务执行结束,dataMap。get(jobDesc));}}
  9。在IDEA开发工具配置参数或将项目打包成jar并通过命令行传参执行(如typejob1,job2),即可看到传入参数对应的任务已开始执行
投诉 评论 转载

小儿蛔虫性肠梗阻的临床表现有哪些蛔虫性肠梗阻,相信大多数朋友都不明白这个是什么,其实它是小儿时期常见的急腹症之一。可引起蛔虫性肠梗阻、胆道蛔虫、蛔虫性腹膜炎等并发症。下面就跟我们一起来了解下小儿蛔虫性肠梗阻的……SpringBootQuartz实现动态定时任务(非数据库模在日常工作中,经常会遇到一些定时任务,比如定时发邮件、异构数据库同步数据等。目前比较常用的是SpringBootQuartz实现动态定时任务的Web项目,这种模式通常需要建立定……男士应该发现的发型玄妙为了配合你美妙的胡须,也为了加快更改造型的速度,了解发型的玄妙也是门必修课。究竟是指定御用发型师比较重要还是居家打理略胜一筹?答案是,两者缺一不可。掌握技巧之后,让专业发型师的……澳门冠军赛陈梦30大获全胜,横扫名将晋级,再战日本世界冠军北京时间4月18日晚,乒乓球WTT澳门冠军赛继续进行,国乒奥运冠军陈梦登场,迎战中国香港队一姐杜凯琹。虽然杜凯琹曾经有过30击败王曼昱的战绩,但只能算是过年吃顿饺子而已,后来再……迪士尼动画风格恐怖游戏再见甜蜜卡罗尔公布游戏发行商JustForGames宣布与开发商LittleSewingMachine合作,开发一款面向多平台的恐怖冒险游戏《再见甜蜜卡罗尔(goodbyeSweetCarole……孕妇穿对内裤事半功倍怀孕初期和后期,受激素急剧增加的影响,阴道分泌物增多,此时更容易受到感染,如果放任不管,有可能影响胎儿的生长发育。因此孕妇要更注意保持内裤和会阴部清洁,勤换内裤,预防感染。……几款开源的OCR识别项目,收藏备用随着科技的发展,OCR场景随处可见,很多APP也集成如身份证识别,银行卡识别的功能,包括微信都支持截图文件中的文字提取。现在,各大厂商均有提供各种场景的OCR识别的API。但是……复旦校花冯琳落户上海,素颜上镜笑容甜美,23岁读研工作两不误梦想是对未来的向往,是对一个人极限的超越,可以提供人成长和发展的源源不断的动力。学生在教育中成长,已经逐渐脱离青涩,要用梦想激发学习动力,顺利完成学业的同时,探索出一条适合自己……排好造句用排好造句大全31,实际上,我怀疑,是不是一切都被安排好了,你永远也不可能参加你的葬礼。32,世界无车日,希望你做到:以尊重保护环境为荣,以污染破坏环境为耻;以多步行多用自行车为荣,以……心理咨询自我暗示与心想事成在心理治疗中,我发现一个有趣的现象心理治疗的结果竟然与来访者的自我暗示息息相关。Psy525。cn例如,一个来访者如果坚信自己可以从心理治疗中得到帮助,最终一定能心想事成……中国要求在WTO框架下讨论欧盟碳关税独家当地时间15日,中国在世贸组织(WTO)贸易与环境委员会(CTE)会议上提出了就贸易方面和某些环境措施的影响进行专门的多边讨论的建议,首先从今年6月CTE会议上就欧盟碳边界调整……朗诵春天畅想春风拂面,春意盎然。徜徉在花的世界,漫步绿草丛中,春天正以美妙的姿态向我们款款走来。在这个生机勃勃的季节,让我们踔厉奋发,勇毅前行,为了秋的收获,辛勤播种,努力耕耘,洒下希望的……
热爱生命巧妙利用五行气场改善自己的运气金匮要略学习笔记6。166。18老人带孩子也需要批评孩子抗战时期八路军的报刊文物油桃怎么洗干净中兴天机火热预售元预定享新国潮军训生活关于爸爸生日的作文白领健康宝典教你识别过劳信号爆笑英语翻译中国的三字经道教的四大天王是那几位道教有马赵温关四大元帅

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找