目录
0:通过页面管理可视化定时任务
可以通过页面查询全部定时任务,对单个定时任务进行启动,停止,修改,添加等操作。此案例简化前端代码和数据库访问逻辑,通过地址传入id启动和暂停指定的定时任务,后端采用了静态代码块,事先准备了三个定时任务。
1:Java代码实现
controller
// 根据id启动定时任务
@RequestMapping(value = "/startQuartz")
@ResponseBody
public String startQuartz(int id) {
String status = null;
// 根据id启动定时任务3
status = quartzService.startQuartz(id);
return status;
}
// 根据id停止定时任务
@RequestMapping(value = "/stopQuartz")
@ResponseBody
public String stopQuartz(int id) {
String status = null;
status = quartzService.stopQuartz(id);
return status;
}
services
package com.thit.service.impl;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import org.quartz.CronScheduleBuilder;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.thit.entity.Quartz;
import com.thit.service.QuartzService;
import com.thit.service.UserService;
@Service
public class QuartzServiceImpl implements QuartzService{
//静态list代替数据库存取Quartz
static List<Quartz> lists=null;
static {
lists=new ArrayList<>();
Quartz quartz1=new Quartz();
quartz1.setId(1);
quartz1.setName("测试任务1");
quartz1.setDesc("任务一用来注入service");
quartz1.setTaskgroup("job-grop1");
quartz1.setTaskname("job1");
quartz1.setTaskPath("com.thit.job.Job1");
quartz1.setStatus("0");//未启动
quartz1.setCronexpression("0/5 * * ? * *");//5秒执行一次
Quartz quartz2=new Quartz();
quartz2.setId(2);
quartz2.setName("测试任务2");
quartz2.setDesc("任务一用来注入service");
quartz2.setTaskgroup("job-grop2");
quartz2.setTaskname("job2");
quartz2.setTaskPath("com.thit.job.Job2");
quartz2.setStatus("0");//未启动
quartz2.setCronexpression("0/3 * * ? * *");//5秒执行一次
Quartz quartz3=new Quartz();
quartz3.setId(3);
quartz3.setName("测试任务3");
quartz3.setDesc("任务一用来注入service");
quartz3.setTaskgroup("job-grop3");
quartz3.setTaskname("job3");
quartz3.setTaskPath("com.thit.job.Job3");
quartz3.setStatus("0");//未启动
quartz3.setCronexpression("0/10 * * ? * *");//5秒执行一次
lists.add(quartz1);
lists.add(quartz2);
lists.add(quartz3);
}
@Autowired
private Scheduler scheduler;
@Override
public void startAll() {
startQuartz(1);
startQuartz(2);
startQuartz(3);
}
//根据id启动指定的定时任务
public String startQuartz(int id) {
// TODO Auto-generated method stub
Quartz quartz=null;
for (Quartz q: lists) {
if(id== q.getId()) {
quartz=q;
}
}
//1:利用反射得到指定的任务类,创建JobDetail,并且将job实例绑定
Class<?> jobClass = null;
try {
jobClass = Class.forName(quartz.getTaskPath());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JobDetail jobDetail=
JobBuilder.newJob((Class<? extends Job>) jobClass)
.withIdentity(quartz.getTaskname(), quartz.getTaskgroup())
.build();
//2:表达式调度构建器
CronScheduleBuilder scheduleBuilder=CronScheduleBuilder
.cronSchedule(quartz.getCronexpression());
//3:创建触发器,设置执行时间
Trigger trigger=TriggerBuilder.newTrigger().
withIdentity(quartz.getTaskname(), quartz.getTaskgroup())
.withSchedule(scheduleBuilder)
.build();
try {
//4:将定时任务和触发器放入调度器
scheduler.scheduleJob(jobDetail, trigger);
//scheduler.start();
return "startJob:sucess";
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "startJob:fail";
}
//根据id暂停指定的定时任务
public String stopQuartz(int id) {
// TODO Auto-generated method stub
Quartz quartz=null;
for (Quartz q: lists) {
if(id== q.getId()) {
System.out.println("关闭定时任务:"+q.getId());
quartz=q;
}
}
//关闭任务,通过指定定时任务的任务名字和任务组来关闭任务
JobKey jobKey=new JobKey(quartz.getTaskname(), quartz.getTaskgroup());
try {
scheduler.deleteJob(jobKey);
return "closeJob:sucess";
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "closeJob:fail";
}
}
job类如下:job1,job2,job3可以参考如下自定义
public class Job1 implements Job{
//userService是spring容器管理的对象
@Autowired
private UserService userService;
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// TODO Auto-generated method stub
Date date=new Date();
SimpleDateFormat dateFormat=new
SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
System.out.println("-----执行定时任务1------"+dateFormat.format(date));
//job类调用其他service的方法
userService.add();
}
}
工场类如下:解决job中注入spring容器管理的 userService
/**
* @author 79027
*需要继承AdaptableJobFactory
*解决spring无法注入的问题
*/
public class MyJobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
//调用父类的方法
Object jobInstance = super.createJobInstance(bundle);
//进行注入
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
配置文件如下:
<!-- AdaptableJobFactory -->
<bean id="jobFactory" class="com.thit.util.MyJobFactory"></bean>
<!-- 配置调度器工厂 -->
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" autowire="no">
<property name="jobFactory" ref="jobFactory"></property>
</bean>
2:实际访问效果如图
启动具体的三个定时任务
http://localhost:8080/task2/startQuartz?id=1
http://localhost:8080/task2/startQuartz?id=2
http://localhost:8080/task2/startQuartz?id=3
暂停指定的定时任务
http://localhost:8080/task2/stopQuartz?id=1
http://localhost:8080/task2/stopQuartz?id=2
http://localhost:8080/task2/stopQuartz?id=3
3:解决定时任务随着项目的启动而自动启动的问题
package com.thit.util;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.quartz.Scheduler;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import com.thit.service.QuartzService;
import com.thit.service.UserService;
//根据bean的生命周期 在bean初始化之前,随着项目启动调用所有定时任务
@Component
public class MyTimerTask implements
InitializingBean, DisposableBean{
@Autowired
QuartzService quartzService;
@Override
public void destroy() throws Exception {
// TODO Auto-generated method stub
quartzService.stopQuartz(1);
quartzService.stopQuartz(2);
quartzService.stopQuartz(3);
System.out.println("DisposableBean的销毁方法");
}
@Override
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
quartzService.startAll();
System.out.println("---在该bean初始化之前,启动全部定时任务的方法---");
}
}