百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

探究 Spring 的定时任务配置 spring scheduled定时任务

yuyutoo 2024-10-12 00:05 5 浏览 0 评论

作者 | 郭朝兴

责编 | Elle

最近在项目开发中进行了一些Spring定时任务的开发工作,在开发过程中对Spring定时任务的配置方式进行了一些研究,现在对各种配置方式进行一个总结。Scheduled是Spring支持的定时任务配置方式,可以用注解或者配置文件的方式进行配置。

Quartz是一个强大的企业级任务调度框架,Spring中继承并简化了Quartz,它是一个开源的由OpenSymphony维护的项目,开发者能够在Java EE,或单独的Java SE应用中使用它。无论是简单的任务调度,还是复杂的企业级应用,Quartz都能够很好地胜任。

Quartz支持CronTriggerBean,SimpleTriggerBean两种模式,CronTriggerBean比 SimpleTriggerBean功能更强大,它能够控制任务执行的精确时间,比如,早上九点半需要执行某QuartzJobBean中给定的任务。

以下对不同的配置方式分别进行介绍。

通Scheduled注解或者xml配置的方式添加定时任务

ref 是定时任务的类在 Spring中的beanName,method是要执行的方法,fixed-delay 是上一个调用完成后,再次调用的延时,fixed-rate 是 上一个调用开始后,再次调用的延时(不用等待上一次调用完成),cron 是表达式,表示在什么时候进行任务调度。

<task:scheduled-tasks scheduler="scheduler" >
<task:scheduled ref="profitScheduler" method="execute" cron="0 0/2 * * * ?" initial-delay="5000" fixed-delay="3600000" />
</task:scheduled-tasks>
<task:scheduler id="scheduler" pool-size="5" />

也可以采用注解的方式,在需要配置为定时任务的方法上添加@Scheduled(cron = "0 0 3 * * ?"),cron为定时任务表达式,cron表达式支持非常丰富的配置规则。

@Component(“taskJob”) 
public class TaskJob { k
@Scheduled(cron = "0 0 3 * * ?")
public void job1 {
System.out.println(“任务进行中。。。”);
}
}

配置任务执行的线程池信息。task:scheduler用来配置任务调度线程池大小,调度线程在被调度任务完成前不会空闲;task:executor用来配置任务执行器的具体参数,pool-size 可以指定执行线程池的初始大小、最大大小,queue-capacity配置等待执行任务的队列容量,reject-policy当等待队列爆了时的策略,分为丢弃、有任务执行器直接执行等方式。

 <task:executor id="executor" pool-size="10-10000" queue-capacity="5000" rejection-policy="CALLER_RUNS"/>
<task:scheduler id="scheduler" pool-size="1000"/>
<task:annotation-driven executor="executor" scheduler="scheduler"/>

CronTrigger配置方式

CronTrigger 支持比simpleTrigger更具体的调度,CronTrigger支持类似日历的重复间隔。CronTrigger 由MethodInvokingJobDetailFactoryBean、CronTriggerFactoryBean两个类支持。

MethodInvokingJobDetailFactoryBean配置需要定时执行的任务类和方法,targetObject为执行定时任务的bean,targetMethod为执行定时任务的bean中的方法。CronTriggerFactoryBean为定时任务的触发器,用来配置定时任务执行的时间表达式。

 <bean id="sycnMonitorBean" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="monitorService" />
<property name="targetMethod" value="syncMonitor" />
</bean>
<bean id="syncTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="sycnMonitorBean" />
<property name="cronExpression" value="0 */10 * * * ?" />
</bean>

SimpleTigger配置方式

当需要在规定的时间执行一次或者以一定的时间间隔重复出发执行job时,SimpleTrigger 就可以满足要求。SimpleTrigger的属性有:开始时间、结束时间、重复次数、重复时间间隔。

如下示例:首先创建需要执行定时任务的bean,名字为quartzBean。然后配置该bean需要定时执行的方法。Concurrent参数用来配置是否同步执行。如果配置为true,则任务执行时,只有上次执行完成后,才可以进入下一次执行。

SimpleTriggerFactoryBean配置了触发器执行的策略,开始执行的延迟时间及执行的时间间隔。SchedulerFactoryBean用来管理任务计划,是任务的总的管理类。将lazy-init='false'那么容器启动就会执行调度程序。

 <bean id="quartzBean" class="com.abchina.tao.scheduled.QuartzMain">
<property name="scheduler" ref="schedulerManager"></property>
</bean>
<!-- 定义jobdetail -->
<bean id="quartzJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="quartzBean"></property>
<property name="targetMethod" value="startQuartz"></property>
<property name="concurrent" value="false" />
</bean>
<bean id="quartzTrigger"
class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="quartzJobDetail"></property>
<property name="startDelay" value="1000"></property>
<property name="repeatInterval" value="300000"></property>
</bean>
<!-- 任务计划,总管理类-->
<bean id="schedulerManager" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="quartzTrigger" />
</list>
</property>
</bean>

SimpleTrigger与CronTrigger高级应用场景

针对需要将定时任务配置为根据用户的实际运行需要,动态调整任务执行的计划,并准实时生效的情况。可以采用配置页面的方式由用户选择任务的执行计划,然后将各个任务的执行计划添加到数据库中。周期性的从数据库中读取定时任务信息,添加、更新、删除定时任务线程。

当Spring 启动时,就会创建schedulerManager作为总的管理类,由schedulerManager来管理所有的任务,schedulerManager在后台每隔一定的时间(配置)执行一次,来监测数据库中需要创建和更新的定时任务。

schedulerManager读取数据库中的定时任务(任务类、任务方法、执行时间),判断定时触发器中是否存在该任务,如果存在,比较数据库中的任务表达式(cron)是否与当前定时器中的时间一致,如果不一致,更新当前任务时间表达式。如果不存在该任务,将任务加入到定时器中。

此种方式创建任务也是基于MethodInvokingJobDetailFactoryBean,CronTriggerFactoryBean 两个类,但是创建方式为通过代码进行实例化,可以根据实际需要动态的创建,灵活性更加强,使用起来也更加的方便,创建任务有2个步骤,具体如下:

(1)实例化任务

首先实例化MethodInvokingJobDetailFactoryBean,MethodInvokingJobDetailFactoryBean是spring自带的,并将数据库中配置的job相关信息添加到mijdfb,然后调用afterPropertiesSet方法,这个方法会实例化一个JobDetailImpl,并将相应的信息添加到JobDetailImpl中。该过程实例化了需要定时调度的类和方法,并可以向类和方法中传入制定的参数,使用配置文件的方式无法达到对应的效果。

MethodInvokingJobDetailFactoryBean mijdfb=new MethodInvokingJobDetailFactoryBean;
mijdfb.setName(qm.getEnvId);
mijdfb.setTargetObject(beanFactory.getBean("service",Mservice.class));
mijdfb.setTargetMethod("runTask");
mijdfb.setConcurrent(false);
TestEnvDomain params = new TestEnvDomain[1];
params[0] = qm;
mijdfb.setArguments(params);
mijdfb.afterPropertiesSet;
org.quartz.JobDetail jd=new JobDetailImpl;
jd=mijdfb.getObject;
scheduler.addJob(jd, true);

(2)实例化触发器

首先实例化CronTriggerFactoryBean,然后添加对应job的时间表表达式等参数信息,然后调用afterPropertiesSet,这个方法和MethodInvokingJobDetailFactoryBean 中的afterPropertiesSet类似,最终实例化一个CronTriggerImpl

String triggerName=qm.getEnvId +"Trigger";
CronTriggerFactoryBean ctb=new CronTriggerFactoryBean;
ctb.setName(triggerName);
ctb.setCronExpression(qm.getCronExpression);
ctb.setJobDetail(jd);
ctb.afterPropertiesSet;
CronTrigger cronTrigger= ctb.getObject;
scheduler.scheduleJob(cronTrigger);
scheduler.rescheduleJob(cronTrigger.getKey, cronTrigger);

以上对Scheduled注解方式、配置文件方式,CronTriggerFactoryBean,SimpleTriggerFactoryBean配置文件方式,CronTriggerFactoryBean通过java任务管理器动态创建等不同定时任务配置方法进行了较详细的说明。

通过以上各种配置方式的对比,可以看出,各种配置方式操作都不是特别复杂,相对来说Scheduled配置方式更加的轻量级一些,在一些相对不是很复杂、不涉及线程特别多的场景下可以使用。

Quartz配置方式是一种更加重量级、多线程、分布式等场景下的定时任务配置方式。希望对遇到定时任务配置问题的朋友,可以做一些比较,选择合适的定时任务配置方式。

相关推荐

史上最全的浏览器兼容性问题和解决方案

微信ID:WEB_wysj(点击关注)◎◎◎◎◎◎◎◎◎一┳═┻︻▄(页底留言开放,欢迎来吐槽)●●●...

平面设计基础知识_平面设计基础知识实验收获与总结
平面设计基础知识_平面设计基础知识实验收获与总结

CSS构造颜色,背景与图像1.使用span更好的控制文本中局部区域的文本:文本;2.使用display属性提供区块转变:display:inline(是内联的...

2025-02-21 16:01 yuyutoo

写作排版简单三步就行-工具篇_作文排版模板

和我们工作中日常word排版内部交流不同,这篇教程介绍的写作排版主要是用于“微信公众号、头条号”网络展示。写作展现的是我的思考,排版是让写作在网格上更好地展现。在写作上花费时间是有累积复利优势的,在排...

写一个2048的游戏_2048小游戏功能实现

1.创建HTML文件1.打开一个文本编辑器,例如Notepad++、SublimeText、VisualStudioCode等。2.将以下HTML代码复制并粘贴到文本编辑器中:html...

今天你穿“短袖”了吗?青岛最高23℃!接下来几天气温更刺激……

  最近的天气暖和得让很多小伙伴们喊“热”!!!  昨天的气温到底升得有多高呢?你家有没有榜上有名?...

CSS不规则卡片,纯CSS制作优惠券样式,CSS实现锯齿样式

之前也有写过CSS优惠券样式《CSS3径向渐变实现优惠券波浪造型》,这次再来温习一遍,并且将更为详细的讲解,从布局到具体样式说明,最后定义CSS变量,自定义主题颜色。布局...

柠檬科技肖勃飞:大数据风控助力信用社会建设

...

你的自我界限够强大吗?_你的自我界限够强大吗英文

我的结果:A、该设立新的界限...

行内元素与块级元素,以及区别_行内元素和块级元素有什么区别?

行内元素与块级元素首先,CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值,分别为块级(block)、行内(inline)。块级元素:(以下列举比较常...

让“成都速度”跑得潇潇洒洒,地上地下共享轨交繁华
让“成都速度”跑得潇潇洒洒,地上地下共享轨交繁华

去年的两会期间,习近平总书记在参加人大会议四川代表团审议时,对治蜀兴川提出了明确要求,指明了前行方向,并带来了“祝四川人民的生活越来越安逸”的美好祝福。又是一年...

2025-02-21 16:00 yuyutoo

今年国家综合性消防救援队伍计划招录消防员15000名

记者24日从应急管理部获悉,国家综合性消防救援队伍2023年消防员招录工作已正式启动。今年共计划招录消防员15000名,其中高校应届毕业生5000名、退役士兵5000名、社会青年5000名。本次招录的...

一起盘点最新 Chrome v133 的5大主流特性 ?

1.CSS的高级attr()方法CSSattr()函数是CSSLevel5中用于检索DOM元素的属性值并将其用于CSS属性值,类似于var()函数替换自定义属性值的方式。...

竞走团体世锦赛5月太仓举行 世界冠军杨家玉担任形象大使

style="text-align:center;"data-mce-style="text-align:...

学物理能做什么?_学物理能做什么 卢昌海

作者:曹则贤中国科学院物理研究所原标题:《物理学:ASourceofPowerforMan》在2006年中央电视台《对话》栏目的某期节目中,主持人问过我一个的问题:“学物理的人,如果日后不...

你不知道的关于这只眯眼兔的6个小秘密
你不知道的关于这只眯眼兔的6个小秘密

在你们忙着给熊本君做表情包的时候,要知道,最先在网络上引起轰动的可是这只脸上只有两条缝的兔子——兔斯基。今年,它更是迎来了自己的10岁生日。①关于德艺双馨“老艺...

2025-02-21 16:00 yuyutoo

取消回复欢迎 发表评论: