1、前言:前几篇文章讨论的都是静态定时器,也就是一旦服务器启动了,定时规则便无法变动,除非重启服务器,但这在真正运营的时候是不可能的。所以对于客户自定义的定时任务之前的方式都是不可实现的,这就需要动态定时器,本篇文章中的例子是参考了网上某篇博客的,由于时间比较长,所以已经找不到原地址了,望原博主原谅。
2、封装了两个最基本的类:任务类(CustomJob)和任务管理器类(QuartzManager)。
- package com.telek.framework.quartz;
- /**
- * Description:任务封装类,需要进行添加的任务可以new这个类的一个对象设置好属性就行
- * CustomJob.java Create on 2012-11-23 上午9:18:20
- * @author 张景
- * @version 1.0
- * Copyright (c) 2012 telek. All Rights Reserved.
- */
- public class CustomJob {
- public static final int JS_ENABLED = 0; // 任务启用状态
- public static final int JS_DISABLED = 1; // 任务禁用状态
- public static final int JS_DELETE = 2; // 任务已删除状态
- private String jobId; // 任务的Id,一般为所定义Bean的ID
- private String jobName; // 任务的描述
- private String jobGroup; // 任务所属组的名称
- private int jobStatus; // 任务的状态:0:启用;1:禁用;2:已删除
- private String cronExpression; // 定时任务运行时间表达式
- private String memos; // 任务描述
- private Class<?> stateFulljobExecuteClass;// 同步的执行类,需要从StatefulMethodInvokingJob继承
- private Class<?> jobExecuteClass;// 异步的执行类,需要从MethodInvokingJob继承
- public String getJobId() {
- return jobId;
- }
- public void setJobId(String jobId) {
- this.jobId = jobId;
- }
- public String getJobName() {
- return jobName;
- }
- public void setJobName(String jobName) {
- this.jobName = jobName;
- }
- public String getJobGroup() {
- return jobGroup;
- }
- public void setJobGroup(String jobGroup) {
- this.jobGroup = jobGroup;
- }
- public int getJobStatus() {
- return jobStatus;
- }
- public void setJobStatus(int jobStatus) {
- this.jobStatus = jobStatus;
- }
- public String getCronExpression() {
- return cronExpression;
- }
- public void setCronExpression(String cronExpression) {
- this.cronExpression = cronExpression;
- }
- public String getMemos() {
- return memos;
- }
- public void setMemos(String memos) {
- this.memos = memos;
- }
- public Class<?> getStateFulljobExecuteClass() {
- return stateFulljobExecuteClass;
- }
- public void setStateFulljobExecuteClass(Class<?> stateFulljobExecuteClass) {
- this.stateFulljobExecuteClass = stateFulljobExecuteClass;
- }
- public Class<?> getJobExecuteClass() {
- return jobExecuteClass;
- }
- public void setJobExecuteClass(Class<?> jobExecuteClass) {
- this.jobExecuteClass = jobExecuteClass;
- }
- public static int getJsEnabled() {
- return JS_ENABLED;
- }
- public static int getJsDisabled() {
- return JS_DISABLED;
- }
- public static int getJsDelete() {
- return JS_DELETE;
- }
- /**
- * Description:得到该job的Trigger名字
- * Date:2012-11-23
- * @author 张景
- * @param @return
- * @return String
- */
- public String getTriggerName() {
- return this.getJobId() + "Trigger";
- }
- }
- package com.telek.framework.quartz;
- import org.quartz.CronTrigger;
- import org.quartz.JobDataMap;
- import org.quartz.JobDetail;
- import org.quartz.Scheduler;
- import org.quartz.SchedulerException;
- import org.quartz.Trigger;
- import org.quartz.impl.StdScheduler;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- /**
- * Description:任务管理器封装类,对任务的统一管理功能,有增,删,查
- * QuartzManager.java Create on 2012-11-23 上午9:19:15
- * @author 张景
- * @version 1.0
- * Copyright (c) 2012 telek. All Rights Reserved.
- */
- public class QuartzManager {
- private static Scheduler scheduler;
- static {
- ApplicationContext context = new ClassPathXmlApplicationContext(
- "applicationContext-quartz.xml");
- scheduler = (StdScheduler) context.getBean("schedulerFactory");
- }
- /**
- * Description:启动一个自定义的job
- * Date:2012-11-23
- * @author 张景
- * @param @param schedulingJob
- * @param @param paramsMap
- * @param @param isStateFull
- * @param @return
- * @return boolean
- */
- public static boolean enableCronSchedule(CustomJob schedulingJob,
- JobDataMap paramsMap, boolean isStateFull) {
- if (schedulingJob == null) {
- return false;
- }
- try {
- CronTrigger trigger = (CronTrigger) scheduler
- .getTrigger(schedulingJob.getTriggerName(),
- schedulingJob.getJobGroup());
- if (null == trigger) {// 如果不存在该trigger则创建一个
- JobDetail jobDetail = null;
- if (isStateFull) {
- jobDetail = new JobDetail(schedulingJob.getJobId(),
- schedulingJob.getJobGroup(),
- schedulingJob.getStateFulljobExecuteClass());
- } else {
- jobDetail = new JobDetail(schedulingJob.getJobId(),
- schedulingJob.getJobGroup(),
- schedulingJob.getJobExecuteClass());
- }
- jobDetail.setJobDataMap(paramsMap);
- trigger = new CronTrigger(schedulingJob.getTriggerName(),
- schedulingJob.getJobGroup(),
- schedulingJob.getCronExpression());
- scheduler.scheduleJob(jobDetail, trigger);
- } else {// Trigger已存在,那么更新相应的定时设置
- trigger.setCronExpression(schedulingJob.getCronExpression());
- scheduler.rescheduleJob(trigger.getName(), trigger.getGroup(),
- trigger);
- }
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- }
- return true;
- }
- /**
- * Description:禁用一个job
- * Date:2012-11-23
- * @author 张景
- * @param @param jobId
- * @param @param jobGroupId
- * @param @return
- * @return boolean
- */
- public static boolean disableSchedule(String jobId, String jobGroupId) {
- if (jobId.equals("") || jobGroupId.equals("")) {
- return false;
- }
- try {
- Trigger trigger = getJobTrigger(jobId, jobGroupId);
- if (null != trigger) {
- scheduler.deleteJob(jobId, jobGroupId);
- }
- } catch (SchedulerException e) {
- e.printStackTrace();
- return false;
- }
- return true;
- }
- /**
- * Description:得到job的详细信息
- * Date:2012-11-23
- * @author 张景
- * @param @param jobId
- * @param @param jobGroupId
- * @param @return
- * @return JobDetail
- */
- public static JobDetail getJobDetail(String jobId, String jobGroupId) {
- if (jobId.equals("") || jobGroupId.equals("") || null == jobId
- || jobGroupId == null) {
- return null;
- }
- try {
- return scheduler.getJobDetail(jobId, jobGroupId);
- } catch (SchedulerException e) {
- e.printStackTrace();
- return null;
- }
- }
- /**
- * Description:得到job对应的Trigger
- * Date:2012-11-23
- * @author 张景
- * @param @param jobId
- * @param @param jobGroupId
- * @param @return
- * @return Trigger
- */
- public static Trigger getJobTrigger(String jobId, String jobGroupId) {
- if (jobId.equals("") || jobGroupId.equals("") || null == jobId
- || jobGroupId == null) {
- return null;
- }
- try {
- return scheduler.getTrigger(jobId + "Trigger", jobGroupId);
- } catch (SchedulerException e) {
- e.printStackTrace();
- return null;
- }
- }
- }
3、上述类已经封装好,在运用的时候我们不需要去修改。接下来初始化一个任务Job,也就是具体要做的业务(本次是在控制台打印出HelloWorld和当前时间)。注意:这里的HelloWorld类必须继承StatefulMethodInvokingJob,并且重写里面的executeInternal(JobExecutionContext context)方法。
- package com.telek.quartz;
- import java.util.Date;
- import org.quartz.JobExecutionContext;
- import org.quartz.JobExecutionException;
- import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean.StatefulMethodInvokingJob;
- /**
- * Description:具体业务代码,此处输出:HelloWorld+打印时间
- * HelloWorld.java Create on 2012-11-23 上午9:21:29
- * @author 张景
- * @version 1.0
- * Copyright (c) 2012 telek. All Rights Reserved.
- */
- public class HelloWorld extends StatefulMethodInvokingJob {
- @Override
- public void executeInternal(JobExecutionContext context)
- throws JobExecutionException {
- System.out.println("HelloWorld : " + new Date());
- }
- }
4、配置applicationContext-quartz.xml文件,其中只有一句话,只是为了方便scheduler的实例化。
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
- <beans>
- <bean name="schedulerFactory"
- class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
- </bean>
- </beans>
5、写一个测试类StartQuartz
new一个任务封装类,然后set你自己的任务属性,最后调用任务管理类QuartManager的enableCronSchedule方法启动调度器,当然里面还有一些其他方法是提供用户调用的,比如删除等。
- package com.telek.test;
- import com.telek.framework.quartz.CustomJob;
- import com.telek.framework.quartz.QuartzManager;
- import com.telek.quartz.HelloWorld;
- public class StartQuartz {
- /**
- * Description:测试一个自定义的定时器
- * Date:2012-11-23
- * @author 张景
- * @param @param args
- * @return void
- */
- public static void main(String[] args) {
- CustomJob helloWorld = new CustomJob();
- helloWorld.setJobId("helloWorld");
- helloWorld.setJobGroup("helloWorldGroup");
- helloWorld.setJobName("HelloWorldName");
- helloWorld.setMemos("HelloWorld测试定时器的描述");
- helloWorld.setCronExpression("0/6 * * * * ?");
- helloWorld.setStateFulljobExecuteClass(HelloWorld.class);
- QuartzManager.enableCronSchedule(helloWorld, null, true);
- }
- }
6、其实上面看上去内容多,需要我们去做的也就是第二步和第四步,只要配好这两步,你就可以随心地动态定时自己的任务了。
7、最后运行StartQuartz里面的main方法进行测试。
8、观察结果:在控制台上在每分钟6秒的倍数会打印出helloWorld和当前时间。