SpringMvc + Quarzt 动态执行任务实现过程
来源:互联网 发布:李子树下埋死人 知乎 编辑:程序博客网 时间:2024/06/06 16:46
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 2.2.1。
本次遇到的情况是 关于N多个抓取任务的调度,并且由于各任务本身是有关联性,不易改造成标准的Jobs,并考虑到不去入侵和修改原来的任务方法,故期望运用Quartz按照Cron设定的时间去执行指定类和方法。
因为需要保存数据到数据库,设计了一个JavaBean来存储数据结构如下:
public class Quartz { /** 自动编号 */ private Long SCHEDULE_ID; /** 任务名称 */ private String NAME; /** 任务别名 */ private String ALIASNAME; /** 任务分组 */ private String GROUP; /** 任务执行类-全路径 */ private String CLASS; /** 任务执行类-方法 */ private String METHOD; /** 任务Cron表达式 */ private String CRON; /** 任务描述 */ private String DESC; private int STATUS_ID; private Long CREATETIME; private Long UPDATETIME; private int CREATEUSER; private int UPDATEUSER;}
Quartz 将作业划分为:执行器(JobDetail)、触发器(Trigger)、监听器(Listener),简略说就是执行器决定如何执行任务,触发器决定何时执行任务,监听器决定任务到达某状态如何操作。
Quartz典型的JobDetail是实现一个Job接口,然后新建一个触发器去执行该Job。
典型的Quartz应用一:
import java.util.Date; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class HelloJob implements Job { private static Logger _log = LoggerFactory.getLogger(HelloJob.class); public HelloJob() { } public void execute(JobExecutionContext context) throws JobExecutionException { _log.error(" 执行任务: " + new Date()); } }
测试类
import static org.quartz.JobBuilder.newJob; import static org.quartz.TriggerBuilder.newTrigger; import static org.quartz.DateBuilder.*; import java.util.Date; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerFactory; import org.quartz.Trigger; import org.quartz.impl.StdSchedulerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SimpleExample { private static Logger log = LoggerFactory.getLogger(SimpleExample.class); public void run() throws Exception { // 通过SchedulerFactory获取一个调度器实例 SchedulerFactory sf = new StdSchedulerFactory(); Scheduler sched = sf.getScheduler(); Date runTime = evenMinuteDate(new Date()); // 通过过JobDetail封装HelloJob,同时指定Job在Scheduler中所属组及名称,这里,组名为group1,而名称为job1。 JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").build(); // 创建一个SimpleTrigger实例,指定该Trigger在Scheduler中所属组及名称。 // 接着设置调度的时间规则.当前时间运行 Trigger trigger = newTrigger().withIdentity("trigger1", "group1").startAt(runTime).build(); // 注册并进行调度 sched.scheduleJob(job, trigger); // 启动调度器 sched.start(); try { //当前线程等待65秒 Thread.sleep(65L * 1000L); } catch (Exception e) { } //调度器停止运行 sched.shutdown(true); log.error("结束运行。。。。"); } public static void main(String[] args) throws Exception { SimpleExample example = new SimpleExample(); example.run(); } }
典型的Quartz应用二:
<!-- 使用MethodInvokingJobDetailFactoryBean,任务类可以不实现Job接口,通过targetMethod指定调用方法--><bean id="taskJob" class="com.tyyd.dw.task.DataConversionTask"/><bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="group" value="job_work"/> <property name="name" value="job_work_name"/> <!--false表示等上一个任务执行完后再开启新的任务--> <property name="concurrent" value="false"/> <property name="targetObject"> <ref bean="taskJob"/> </property> <property name="targetMethod"> <value>execute</value> </property></bean><!-- 调度触发器 --><bean id="myTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="name" value="work_default_name"/> <property name="group" value="work_default"/> <property name="jobDetail"> <ref bean="jobDetail" /> </property> <property name="cronExpression"> <value>0/5 * * * * ?</value> </property></bean><!-- 调度工厂 --><bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="myTrigger"/> </list> </property></bean>
应用一是常见的java实现方式,没有使用Spring去管理Quartz对象,也反映Quartz可以脱离Spring独立执行。应用二是通过Spring配置文件实现执行实例化类的方法,但是把配置写在XML文件里面非常不方便修改。因此借鉴第二种方法实现Quartz的动态加载任务,同理也可实现增加、删除、暂停、启动、单次执行等功能。
考虑到Quartz调度工厂不需要多例,并且考虑注入的便捷性,在SpringMvc.xml文件里配置:
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"/>
并将其注入到SchedulerJobService中。
package cn.focus.sh.core.quartz.service;import java.util.List;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import javax.annotation.PostConstruct;import org.quartz.CronScheduleBuilder;import org.quartz.CronTrigger;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.TriggerBuilder;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;import org.springframework.stereotype.Service;@Servicepublic class ScheduleJobService { @Autowired private Scheduler scheduler; private static Map<String,Quartz> QuartzMap = new ConcurrentHashMap<String,Quartz>(); @Autowired SpringUtils utils; @Autowired private QuartzDao quartzDao; @PostConstruct public void init(){ //从数据库初始化任务列表 List<Quartz> list = quartzDao.selectAll(); for(Quartz quartz :list){ run(quartz); } } public void run(Quartz quartz){ MethodInvokingJobDetailFactoryBean bean =new MethodInvokingJobDetailFactoryBean(); try { Class<?> loader = Class.forName(quartz.getCLASS()); bean.setTargetObject(utils.getBean(loader)); bean.setTargetClass(loader); bean.setTargetMethod(quartz.getMETHOD()); bean.setGroup(quartz.getGROUP()); bean.setName(quartz.getNAME()); bean.setConcurrent(false); bean.afterPropertiesSet(); //表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartz.getCRON()); //按新的cronExpression表达式构建一个新的trigger CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(quartz.getNAME(), quartz.getGROUP()) .withSchedule(scheduleBuilder).build(); try { scheduler.scheduleJob(bean.getObject(), trigger); } catch (SchedulerException e) { e.printStackTrace(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
CLASS cn.xxx.xxx.manager.xxxManager
METHOD getCount
CRON 0/10 * * * * ?
目前只实现了动态执行任务,同理可以实现动态暂停、删除、增加、修改等功能。
- SpringMvc + Quarzt 动态执行任务实现过程
- Java Quarzt定时任务的实现
- Quarzt.NET 任务调度框架
- Quarzt.NET 任务调度框架
- spring任务调度quarzt的配置
- MySQL存储过程实现动态执行SQL
- springMvc执行过程,什么是SpringMvc
- Spark_任务执行过程
- Springmvc框架执行过程
- springMVC执行过程
- SpringMVC定时任务 执行两次
- springmvc中执行异步任务
- SpringMVC 配置定时执行任务
- Springmvc 定时任务执行两次
- springmvc中实现quartz定时任务(每分钟的第3秒执行任务调度方法)
- springmvc中实现quartz定时任务(每分钟的第3秒执行任务调度方法)
- SpringMvc实现定时任务
- 动态链接执行过程
- Android 开源框架Universal-Image-Loader完全解析(二)--- 图片缓存策略详解
- 2012年5月SAT香港真题解析
- 深入浅出Spark视频
- JAVA线程的初步学习
- OpenCV2.1的安装和VS2008的设置
- SpringMvc + Quarzt 动态执行任务实现过程
- pig的 Replicated Join 失败
- android 自定义控件字体,解决字体偏移,卡顿,代码重复等问题
- Pig的一个小问题 (filter之后 没有数据)
- Python学习之语句、列表
- Tiled Layer层空报错问题
- 无题
- MFC打开一个文件
- cocos2dx实现电脑Enter、Escape、方向键的响应