Spring+Quartz实现动态添加定时任务

版权声明:本文为博主原创文章,转载请附上原文链接,谢谢! https://blog.csdn.net/qq_21454973/article/details/81979660

老规矩,吃水不忘挖井人:挖井人一,挖井人二.

以上,感谢。

首先引入jar:

<!-- quartz定时任务 -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-jobs</artifactId>
            <version>2.2.1</version>
        </dependency>

然后数据库,两个表,如图:

s_timetask:

s_timetask_log:

mapper/model/dao层用mybatis generator 自动生成,此处省略;

service/impl也没有写逻辑,此处省略;

各类我放入一个package中:

public class InitQuartzJob implements ApplicationContextAware {
	private static final Logger logger = Logger.getLogger(InitQuartzJob.class);
	private static ApplicationContext appCtx;
	public static SchedulerFactoryBean schedulerFactoryBean = null;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		// TODO Auto-generated method stub
		if (this.appCtx == null) {
			this.appCtx = applicationContext;
		}
	}

	public static void init() {
		/*
		 * STimetaskService sTimetaskService = (STimetaskService)
		 * SpingInit.getApplicationContext().getBean("sTimetaskServiceImpl");
		 */
		STimetaskService sTimetaskService = (STimetaskService) SpringUtils.getBean(STimetaskService.class);

		schedulerFactoryBean = (SchedulerFactoryBean) appCtx.getBean(SchedulerFactoryBean.class);
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		try {
			logger.info(scheduler.getSchedulerName());
		} catch (SchedulerException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		// 这里从数据库中获取任务信息数据
		STimetaskExample example = new STimetaskExample();
		STimetaskExample.Criteria c = example.createCriteria();
		c.andJobStatusEqualTo("1"); // 已发布的定时任务
		List<STimetask> list = sTimetaskService.selectByExample(example);
		List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
		for (STimetask sTimetask : list) {
			ScheduleJob job1 = new ScheduleJob();
			job1.setJobId(sTimetask.getId());
			job1.setJobGroup(sTimetask.getGroupName()); // 任务组
			job1.setJobName(sTimetask.getName());// 任务名称
			job1.setJobStatus(sTimetask.getJobStatus()); // 任务发布状态
			job1.setIsConcurrent(sTimetask.getIsConcurrent() == 1 ? "1" : "0"); // 运行状态
																				// 1:run
																				// 0:stop
			job1.setCronExpression(sTimetask.getCron());
			job1.setBeanClass(sTimetask.getBeanName());// 一个以所给名字注册的bean的实例
			job1.setMethodName(sTimetask.getMethodName());
			job1.setJobData(sTimetask.getJobData()); // 参数
			jobList.add(job1);
		}

		for (ScheduleJob job : jobList) {
			try {
				addJob(job);
			} catch (SchedulerException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 添加任务
	 * 
	 * @param scheduleJob
	 * @throws SchedulerException
	 */
	public static void addJob(ScheduleJob job) throws SchedulerException {
		if (job == null || !ScheduleJob.STATUS_RUNNING.equals(job.getJobStatus())) {
			return;
		}
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		logger.info(scheduler + "...........................................add");
		TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
		CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
		// 不存在,创建一个
		if (null == trigger) {
			Class clazz = ScheduleJob.CONCURRENT_IS.equals(job.getIsConcurrent()) ? QuartzJobFactory.class
					: QuartzJobFactoryDisallowConcurrentExecution.class;
			JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(job.getJobName(), job.getJobGroup())
					.usingJobData("data", job.getJobData()).build();
			jobDetail.getJobDataMap().put("scheduleJob", job);
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
			trigger = TriggerBuilder.newTrigger().withDescription(job.getJobId().toString())
					.withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();
			scheduler.scheduleJob(jobDetail, trigger);
		} else {
			// Trigger已存在,那么更新相应的定时设置
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());

			// 按新的cronExpression表达式重新构建trigger
			trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).usingJobData("data", job.getJobData())
					.withSchedule(scheduleBuilder).build();

			// 按新的trigger重新设置job执行
			scheduler.rescheduleJob(triggerKey, trigger);
		}
		if ("0".equals(job.getIsConcurrent())) {
			JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());
			scheduler.pauseJob(jobKey);
		}
	}

}
public class QuartzJobFactory implements Job {
	public final Logger log = Logger.getLogger(this.getClass());
 
 
	public void execute(JobExecutionContext context) throws JobExecutionException {
		ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
		TaskUtils.invokMethod(scheduleJob);
	}
}
@DisallowConcurrentExecution
public class QuartzJobFactoryDisallowConcurrentExecution implements Job {
  public final Logger log = Logger.getLogger(this.getClass());
 
 
  public void execute(JobExecutionContext context) throws JobExecutionException {
      ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
      TaskUtils.invokMethod(scheduleJob);
 
 
  }
}
public class ScheduleJob {
	public static final String STATUS_RUNNING = "1"; // 正在运行

	public static final String STATUS_NOT_RUNNING = "0"; // 已停止

	public static final String CONCURRENT_IS = "1";

	public static final String CONCURRENT_NOT = "0";

	private String jobId;

	private Date createTime;

	private Date updateTime;

	/**
	 * 任务名称
	 */
	private String jobName;

	/**
	 * 任务分组
	 */
	private String jobGroup;

	/**
	 * 任务状态 是否启动任务
	 */
	private String jobStatus;

	/**
	 * cron表达式
	 */
	private String cronExpression;

	/**
	 * 描述
	 */
	private String description;

	/**
	 * 任务执行时调用哪个类的方法 包名+类名
	 */
	private String beanClass;

	/**
	 * 任务是否有状态
	 */
	private String isConcurrent;

	/**
	 * spring bean
	 */
	private String springId;

	/**
	 * 任务调用的方法名
	 */
	private String methodName;

	private String jobData;

	public String getJobData() {
		return jobData;
	}

	public void setJobData(String jobData) {
		this.jobData = jobData;
	}

	public String getSpringId() {
		return springId;
	}

	public void setSpringId(String springId) {
		this.springId = springId;
	}

	public String getJobId() {
		return jobId;
	}

	public void setJobId(String jobId) {
		this.jobId = jobId;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public Date getUpdateTime() {
		return updateTime;
	}

	public void setUpdateTime(Date updateTime) {
		this.updateTime = updateTime;
	}

	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 String getJobStatus() {
		return jobStatus;
	}

	public void setJobStatus(String jobStatus) {
		this.jobStatus = jobStatus;
	}

	public String getCronExpression() {
		return cronExpression;
	}

	public void setCronExpression(String cronExpression) {
		this.cronExpression = cronExpression;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getBeanClass() {
		return beanClass;
	}

	public void setBeanClass(String beanClass) {
		this.beanClass = beanClass;
	}

	public String getIsConcurrent() {
		return isConcurrent;
	}

	public void setIsConcurrent(String isConcurrent) {
		this.isConcurrent = isConcurrent;
	}

	public String getMethodName() {
		return methodName;
	}

	public void setMethodName(String methodName) {
		this.methodName = methodName;
	}

}
public class TaskUtils {
  public final static Logger log = Logger.getLogger(TaskUtils.class);
 
  private static STimetaskLogService sTimetaskLogService = (STimetaskLogService)
		  SpringUtils.getBean(STimetaskLogService.class);
  /**
   * 通过反射调用scheduleJob中定义的方法
   * 
   * @param scheduleJob
   */
  @SuppressWarnings("unchecked")
  public static void invokMethod(ScheduleJob scheduleJob) {
    Object object = null;
    Class clazz = null;
    boolean flag = true;
    if (StringUtils.isNotBlank(scheduleJob.getSpringId())) {
      object = SpringUtils.getBean(scheduleJob.getSpringId());
    } else if (StringUtils.isNotBlank(scheduleJob.getBeanClass())) {
      try {
        clazz = Class.forName(scheduleJob.getBeanClass());
        object = clazz.newInstance();
      } catch (Exception e) {
        flag = false;
        STimetaskLog tlog = new STimetaskLog();
        tlog.setId(UuidUtils.creatUUID());
        tlog.setCreateDate(new Date());
        tlog.setJobId(scheduleJob.getJobId().toString());
        tlog.setReason("未找到"+scheduleJob.getBeanClass()+"对应的class");
        tlog.setState("fail");
        sTimetaskLogService.insertSelective(tlog);
        e.printStackTrace();
      }
 
 
    }
    if (object == null) {
      flag = false;
      log.error("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,请检查是否配置正确!!!");
      STimetaskLog tlog = new STimetaskLog();
      tlog.setId(UuidUtils.creatUUID());
      tlog.setCreateDate(new Date());
      tlog.setJobId(scheduleJob.getJobId().toString());
      tlog.setReason("未找到"+scheduleJob.getBeanClass()+"对应的class");
      tlog.setState("fail");
      sTimetaskLogService.insertSelective(tlog);
      return;
    }
    clazz = object.getClass();
    Method method = null;
    try {
      method = clazz.getDeclaredMethod(scheduleJob.getMethodName(), new Class[] { String.class });
    } catch (NoSuchMethodException e) {
      flag = false;
      log.error("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,方法名设置错误!!!");
      STimetaskLog tlog = new STimetaskLog();
      tlog.setId(UuidUtils.creatUUID());
      tlog.setCreateDate(new Date());
      tlog.setJobId(scheduleJob.getJobId().toString());
      tlog.setReason("未找到"+scheduleJob.getBeanClass()+"类下"+scheduleJob.getMethodName()+"对应的方法");
      tlog.setState("fail");
      sTimetaskLogService.insertSelective(tlog);
    } catch (SecurityException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    if (method != null) {
      try {
        method.invoke(object, scheduleJob.getJobData());
      } catch (IllegalAccessException e) {
        flag = false;
        STimetaskLog tlog = new STimetaskLog();
        tlog.setId(UuidUtils.creatUUID());
        tlog.setCreateDate(new Date());
        tlog.setJobId(scheduleJob.getJobId().toString());
        tlog.setReason("未找到"+scheduleJob.getBeanClass()+"类下"+scheduleJob.getMethodName()+"对应的方法参数设置错误");
        tlog.setState("fail");
        sTimetaskLogService.insertSelective(tlog);
        e.printStackTrace();
      } catch (IllegalArgumentException e) {
        flag = false;
        STimetaskLog tlog = new STimetaskLog();
        tlog.setId(UuidUtils.creatUUID());
        tlog.setCreateDate(new Date());
        tlog.setJobId(scheduleJob.getJobId().toString());
        tlog.setReason("未找到"+scheduleJob.getBeanClass()+"类下"+scheduleJob.getMethodName()+"对应的方法参数设置错误");
        tlog.setState("fail");
        sTimetaskLogService.insertSelective(tlog);
        e.printStackTrace();
      } catch (InvocationTargetException e) {
        flag = false;
        STimetaskLog tlog = new STimetaskLog();
        tlog.setId(UuidUtils.creatUUID());
        tlog.setCreateDate(new Date());
        tlog.setJobId(scheduleJob.getJobId().toString());
        tlog.setReason("未找到"+scheduleJob.getBeanClass()+"类下"+scheduleJob.getMethodName()+"对应的方法参数设置错误");
        tlog.setState("fail");
        sTimetaskLogService.insertSelective(tlog);
        e.printStackTrace();
      }
    }
    if(flag){
      System.out.println("任务名称 = [" + scheduleJob.getJobName() + "]----------启动成功");
      STimetaskLog tlog = new STimetaskLog();
      tlog.setId(UuidUtils.creatUUID());
      tlog.setCreateDate(new Date());
      tlog.setJobId(scheduleJob.getJobId().toString());
      tlog.setState("success");
      sTimetaskLogService.insertSelective(tlog);
    }
    
  }
}

InitQuartzJob 是程序初始化定时任务,QuartzJobFactory 是管理的工厂类(其实我也不知道干啥的...),ScheduleJob 是定时任务的实体类,TaskUtils 是定时任务的执行结果,会入库到表.

管理定时任务的类:

@Controller
@RequestMapping(value = "/admin/task")
public class ManageTimetaskController {
	static Logger logger = Logger.getLogger(ManageTimetaskController.class);
	@Autowired
	STimetaskService sTimetaskService;
	@Autowired
	private SchedulerFactoryBean schedulerFactoryBean;
	@Autowired
	private ThreadPoolTaskExecutor threadPoolTaskExecutor;
	@SystemControllerLog(description="增加定时任务")
	@RequestMapping(value = "/add", produces = "text/html;charset=UTF-8;", method = RequestMethod.POST)
	@ResponseBody
	public String add(HttpServletRequest request, HttpSession httpSession) {
		String code = "";
		String message = "";
		String data = null;
		try {
			Managers manager = (Managers) httpSession.getAttribute("managers");
			if (manager == null) {
				code = "200";
				message = "用户登录异常";
				return GiveBack.make(code, message, data);
			}
			String name = request.getParameter("name");
			String desccription = request.getParameter("desccription");
			String cron = request.getParameter("cron");
			String jobStatus = request.getParameter("jobStatus");
			String jobData = request.getParameter("jobData");
			String methodName = request.getParameter("methodName");
			if (StringUtils.isBlank(name) || StringUtils.isBlank(desccription) || StringUtils.isBlank(cron)
					|| StringUtils.isBlank(jobStatus) || StringUtils.isBlank(jobData) || StringUtils.isBlank(methodName)
					) {
				code = "200";
				message = "必要参数为空";
				return GiveBack.make(code, message, data);
			}
			if (name.length() > 50 || desccription.length() > 1000 || (!isValidExpression(cron)) || (!isOne(jobStatus))
					|| jobData.length() > 2000 || (!checkMethodName(methodName))) {
				code = "201";
				message = "参数异常";
				return GiveBack.make(code, message, data);
			}
			
			String[] ipList = jobData.split(",");
			for (int i = 0; i < ipList.length; i++) {
				String tempIp = ipList[i];
				if(!isIP(tempIp)){
					code = "201";
					message = "jobData异常";
					return GiveBack.make(code, message, data);
				}
			}

			STimetask record = new STimetask();
			record.setId(UuidUtils.creatUUID());

			record.setName(name);
			record.setGroupName("pdu");
			Date date = new Date();
			record.setStartTime(date);
			record.setEndTime(date);
			record.setCron(cron);
			record.setJobStatus(jobStatus);
			record.setIsConcurrent(0);
			record.setPlanStatus("-1");
			record.setJobData(jobData);
			record.setMethodName(methodName);
			
			record.setBeanName("com.utils.tprs_pdu.TPRSOrderSendHelper");
			record.setDesccription(desccription);
			record.setCreateUserId(manager.getId());
			record.setCreateDate(date);
			int i = sTimetaskService.insertSelective(record);
			if (i < 1) {
				code = "1";
				message = "请求成功但未发生任何更改";
				return GiveBack.make(code, message, data);
			}
			code = "0";
			return GiveBack.make(code, message, data);
		} catch (Exception e) {
			code = "-1";
			message = "系统异常";
			return GiveBack.make(code, message, data);
		}
	}

	@SystemControllerLog(description="删除定时任务")
	@RequestMapping(value = "/del", produces = "text/html;charset=UTF-8;", method = RequestMethod.POST)
	@ResponseBody
	public String del(HttpServletRequest request, HttpSession httpSession) {
		String code = "";
		String message = "";
		String data = null;

		try {
			String id = request.getParameter("id");
			
			String[] idList = id.split(",");
			JSONArray arr = new JSONArray();
			code = "0";
			for (int i = 0; i < idList.length; i++) {
				JSONObject json = new JSONObject();
				String singleId = idList[i];
				final STimetask sTimetask = sTimetaskService.selectByPrimaryKey(singleId);
				final String name = sTimetask.getName();
				final String groupName = sTimetask.getGroupName();
				int res = sTimetaskService.deleteByPrimaryKey(singleId);
				if (res < 1) {
					code = "1";
					json.put(singleId, "请求成功但未发生任何更改");
				}else{
					json.put(singleId, "请求成功");
				}
				Scheduler scheduler = schedulerFactoryBean.getScheduler();
				JobKey jobKey = JobKey.jobKey(name, groupName);
				try {
					scheduler.deleteJob(jobKey);
				} catch (SchedulerException e1) {
					e1.printStackTrace();
					code = "-1";
					json.put(singleId, "系统异常导致任务删除成功,但计划仍在执行,请联系管理员");
				}
				arr.add(json);
			}
			data = arr.toJSONString();
			return GiveBack.make(code, message, data);
		} catch (Exception e) {
			code = "-1";
			message = "系统异常";
			return GiveBack.make(code, message, data);
		}
	}
	
	@SystemControllerLog(description="更新定时任务")
	@RequestMapping(value = "/update", produces = "text/html;charset=UTF-8;", method = RequestMethod.POST)
	@ResponseBody
	public String update(HttpServletRequest request, HttpSession httpSession) {
		String code = "";
		String message = "";
		String data = null;

		try {
			Managers manager = (Managers) httpSession.getAttribute("managers");
			if (manager == null) {
				code = "200";
				message = "用户登录异常";
				return GiveBack.make(code, message, data);
			}
			final String id = request.getParameter("id");
			String name = request.getParameter("name");
			String desccription = request.getParameter("desccription");
			String cron = request.getParameter("cron");
			String jobStatus = request.getParameter("jobStatus");
			String jobData = request.getParameter("jobData");
			String methodName = request.getParameter("methodName");
			if (StringUtils.isBlank(name) || StringUtils.isBlank(desccription) || StringUtils.isBlank(cron)
					|| StringUtils.isBlank(jobStatus) || StringUtils.isBlank(jobData) || StringUtils.isBlank(methodName)
					) {
				code = "200";
				message = "必要参数为空";
				return GiveBack.make(code, message, data);
			}
			if (name.length() > 50 || desccription.length() > 1000 || (!isValidExpression(cron)) || (!isOne(jobStatus))
					|| jobData.length() > 2000 || (!checkMethodName(methodName)) ) {
				code = "201";
				message = "参数异常";
				return GiveBack.make(code, message, data);
			}

			STimetask record = new STimetask();
			record.setId(id);
			record.setName(name);
			record.setGroupName("pdu");
			Date date = new Date();
			record.setStartTime(date);
			record.setEndTime(date);
			record.setCron(cron);
			record.setJobStatus(jobStatus);
			record.setJobData(jobData);
			record.setMethodName(methodName);
			
			record.setBeanName("com.utils.tprs_pdu.TPRSOrderSendHelper");
			record.setDesccription(desccription);
			record.setModifyUserId(manager.getId());
			record.setModifyDate(date);
			int i = sTimetaskService.updateByPrimaryKeySelective(record);
			if (i < 1) {
				code = "1";
				message = "请求成功但未发生任何更改";
				return GiveBack.make(code, message, data);
			}else{
				code = "0";
				threadPoolTaskExecutor.execute(new Thread(id){
					public void run() {
						STimetask sTimetask = sTimetaskService.selectByPrimaryKey(id);
						if("1".equals(sTimetask.getJobStatus())&&"1".equals(sTimetask.getPlanStatus())
								&&"1".equals(""+sTimetask.getIsConcurrent())){
							Scheduler scheduler = schedulerFactoryBean.getScheduler();
							JobKey jobKey = JobKey.jobKey(sTimetask.getName(), sTimetask.getGroupName());
							try {
								scheduler.deleteJob(jobKey);
							} catch (SchedulerException e1) {
								e1.printStackTrace();
							}
							ScheduleJob job1 = new ScheduleJob();
							job1.setJobId(sTimetask.getId());
							job1.setJobGroup(sTimetask.getGroupName()); // 任务组
							job1.setJobName(sTimetask.getName());// 任务名称
							job1.setJobStatus(sTimetask.getJobStatus()); // 任务发布状态
							job1.setIsConcurrent(sTimetask.getIsConcurrent() == 1 ? "1" : "0"); // 运行状态
																								// 1:run
																								// 0:stop
							job1.setCronExpression(sTimetask.getCron());
							job1.setBeanClass(sTimetask.getBeanName());// 一个以所给名字注册的bean的实例
							job1.setMethodName(sTimetask.getMethodName());
							job1.setJobData(sTimetask.getJobData()); // 参数
							try {
								InitQuartzJob.addJob(job1);
							} catch (SchedulerException e) {
								e.printStackTrace();
							}
							sTimetask.setIsConcurrent(1);
							sTimetask.setPlanStatus("1");
							sTimetaskService.updateByPrimaryKeySelective(sTimetask);
						}
					}
				});
				return GiveBack.make(code, message, data);
			}
		} catch (Exception e) {
			code = "-1";
			message = "系统异常";
			return GiveBack.make(code, message, data);
		}
	}
	
	@RequestMapping(value = "/get", produces = "text/html;charset=UTF-8;", method = RequestMethod.POST)
	@ResponseBody
	public String get(HttpServletRequest request, HttpSession httpSession) {
		String code = "";
		String message = "";
		String data = null;
		try {
			String pageNumStr = request.getParameter("pageNum");
			String pageSizeStr = request.getParameter("pageSize");
			
			STimetaskExample example = new STimetaskExample();
			STimetaskExample.Criteria criteria = example.createCriteria();
			String name = request.getParameter("name");
			String jobStatus = request.getParameter("jobStatus");
			if(StringUtils.isNotEmpty(name)){
				criteria.andNameLike("%"+name+"%");
			}
			out:if(StringUtils.isNotEmpty(jobStatus)){
				if("-1".equals(jobStatus)){
					break out;
				}
				if(!"1".equals(jobStatus)&&!"0".equals(jobStatus)){
					code = "201";
					message = "参数异常";
					return GiveBack.make(code, message, data);
				}
				criteria.andJobStatusEqualTo(jobStatus);
			}
			int pageNum = 0;
			int pageSize = 0;
			try {
				pageNum = Integer.parseInt(pageNumStr);
				pageSize = Integer.parseInt(pageSizeStr);
			} catch (Exception e) {
				code = "100";
				message = "类型转换异常";
				return GiveBack.make(code, message, data);
			}
			Page<STimetask> page = sTimetaskService.pageSelectByExample(example, pageNum, pageSize);
			List<STimetask> list = page.subList(0, page.size());
			JSONObject json = new JSONObject();
			json.put("pages",page.getPages());
			json.put("totals",page.getTotal());
			message = json.toString();
			JSONArray arr = new JSONArray();
			if(list.size() == 0){
				data = "";
			}else{
				for (int i = 0; i < list.size(); i++) {
					JSONObject json2 = new JSONObject();
					STimetask s = list.get(i);
					json2.put("id", s.getId());
					json2.put("desccription", s.getDesccription() == null?"":s.getDesccription());
					json2.put("name", s.getName() == null?"":s.getName());
					json2.put("cron", s.getCron() == null?"":s.getCron());
					json2.put("jobStatus", s.getJobStatus() == null?"":s.getJobStatus());
					json2.put("isCon", s.getIsConcurrent() == null?"":s.getIsConcurrent());
					json2.put("planStatus", s.getPlanStatus() == null?"":s.getPlanStatus());
					json2.put("jobData", s.getJobData() == null?"":s.getJobData());
					json2.put("methodName", s.getMethodName() == null?"":s.getMethodName());
					json2.put("createUserId",s.getCreateUserId() == null?"":s.getCreateUserId());
					json2.put("createTime", s.getCreateDate().toLocaleString() == null?"":s.getCreateDate().toLocaleString());
					json2.put("modifyUserId",s.getModifyUserId() == null?"":s.getModifyUserId());
					json2.put("modifyTime", s.getModifyDate() == null?"":s.getModifyDate());
					arr.add(json2);
				}
			}
			code = "0";
			data = arr.toJSONString();
			return GiveBack.make(code, message, data);
		} catch (Exception e) {
			code = "-1";
			message = e.toString();
			return GiveBack.make(code, message, data);
		}
	}
	
	
	

	private static boolean isOne(String str) {
		return "1".equals(str) || "0".equals(str) ? true : false;
	}

	private static boolean checkMethodName(String str) {
		if (StringUtils.isBlank(str)) {
			return false;
		}
		String[] names = { "open", "close" };
		boolean res = false;
		for (int i = 0; i < names.length; i++) {
			if (str.equals(names[i])) {
				res = true;
			}
		}
		return res;
	}

	private static boolean isValidExpression(final String cronExpression) {
		CronTriggerImpl trigger = new CronTriggerImpl();
		try {
			trigger.setCronExpression(cronExpression);
			Date date = trigger.computeFirstFireTime(null);
			return date != null && date.after(new Date());
		} catch (Exception e) {
			logger.error("[TaskUtils.isValidExpression]:failed. throw ex:" + e);
		}
		return false;
	}
	
	private static boolean isIP(String ip) {
		String rexp = "([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}";
		return ip.matches(rexp);
	}
	
}

定时任务控制的类:

@Controller
@RequestMapping(value = "/admin/task")
public class TimetaskController {

	static Logger logger = Logger.getLogger(ManageTimetaskController.class);
	@Autowired
	STimetaskService sTimetaskService;
	@Autowired
	private SchedulerFactoryBean schedulerFactoryBean;


	@SystemControllerLog(description="加入计划")
	@RequestMapping(value = "/addJob", produces = "text/html;charset=UTF-8;")
	@ResponseBody
	public String addJob(HttpServletRequest request, HttpSession httpSession) {
		String code = "";
		String message = "";
		String data = null;

		String id = request.getParameter("id");
		STimetask sTimetask = sTimetaskService.selectByPrimaryKey(id);
		if (sTimetask == null) {
			code = "404";
			message = "未找到该任务";
			return GiveBack.make(code, message, data);
		}
		//发布即启动
		/*if(!"1".equals(sTimetask.getJobStatus())){
			code = "1";
			message = "请先发布任务";
			return GiveBack.make(code, message, data);
		}*/
		if("1".equals(sTimetask.getPlanStatus())){
			code = "1";
			message = "该任务已启动";
			return GiveBack.make(code, message, data);
		}
		sTimetask.setJobStatus("1");
		sTimetask.setIsConcurrent(1);
		sTimetask.setPlanStatus("1");
		ScheduleJob job1 = new ScheduleJob();
		job1.setJobId(sTimetask.getId());
		job1.setJobGroup(sTimetask.getGroupName()); // 任务组
		job1.setJobName(sTimetask.getName());// 任务名称
		job1.setJobStatus(sTimetask.getJobStatus()); // 任务发布状态
		job1.setIsConcurrent(sTimetask.getIsConcurrent() == 1 ? "1" : "0"); // 运行状态
																			// 1:run
																			// 0:stop
		job1.setCronExpression(sTimetask.getCron());
		job1.setBeanClass(sTimetask.getBeanName());// 一个以所给名字注册的bean的实例
		job1.setMethodName(sTimetask.getMethodName());
		job1.setJobData(sTimetask.getJobData()); // 参数
		try {
			InitQuartzJob.addJob(job1);
			sTimetaskService.updateByPrimaryKeySelective(sTimetask);
			code = "0";
			return GiveBack.make(code, message, data);
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			code = "-1";
			message = "系统异常,任务启动失败";
			return GiveBack.make(code, message, data);
		}
	}
	
	@SystemControllerLog(description="强制重启")
	@RequestMapping(value = "/powerStartJob", produces = "text/html;charset=UTF-8;")
	@ResponseBody
	public String powerStartJob(HttpServletRequest request, HttpSession httpSession) {
		String code = "";
		String message = "";
		String data = null;

		String id = request.getParameter("id");
		STimetask sTimetask = sTimetaskService.selectByPrimaryKey(id);
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(sTimetask.getName(), sTimetask.getGroupName());
		try {
			scheduler.deleteJob(jobKey);
		} catch (SchedulerException e1) {
			e1.printStackTrace();
		}
		ScheduleJob job1 = new ScheduleJob();
		sTimetask.setJobStatus("1");
		sTimetask.setIsConcurrent(1);
		sTimetask.setPlanStatus("1");
		job1.setJobId(sTimetask.getId());
		job1.setJobGroup(sTimetask.getGroupName()); // 任务组
		job1.setJobName(sTimetask.getName());// 任务名称
		job1.setJobStatus(sTimetask.getJobStatus()); // 任务发布状态
		job1.setIsConcurrent(sTimetask.getIsConcurrent() == 1 ? "1" : "0"); // 运行状态
																			// 1:run
																			// 0:stop
		job1.setCronExpression(sTimetask.getCron());
		job1.setBeanClass(sTimetask.getBeanName());// 一个以所给名字注册的bean的实例
		job1.setMethodName(sTimetask.getMethodName());
		job1.setJobData(sTimetask.getJobData()); // 参数
		try {
			InitQuartzJob.addJob(job1);
			sTimetaskService.updateByPrimaryKeySelective(sTimetask);
			code = "0";
			return GiveBack.make(code, message, data);
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			code = "-1";
			message = "系统异常,任务启动失败";
			return GiveBack.make(code, message, data);
		}
	}
	
	@SystemControllerLog(description="暂停计划")
	@RequestMapping(value = "/stopJob", produces = "text/html;charset=UTF-8;")
	@ResponseBody
	public String stopJob(HttpServletRequest request, HttpSession httpSession) {
		String code = "";
		String message = "";
		String data = null;

		String id = request.getParameter("id");
		STimetask sTimetask = sTimetaskService.selectByPrimaryKey(id);
		if (sTimetask == null) {
			code = "404";
			message = "未找到该任务";
			return GiveBack.make(code, message, data);
		}
		if(!"1".equals(sTimetask.getPlanStatus())){
			code = "1";
			message = "请先加入计划";
			return GiveBack.make(code, message, data);
		}
		if("0".equals(sTimetask.getPlanStatus())){
			code = "1";
			message = "该任务已暂停";
			return GiveBack.make(code, message, data);
		}
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(sTimetask.getName(), sTimetask.getGroupName());
		try {
			scheduler.pauseJob(jobKey);
			sTimetask.setIsConcurrent(0);
			sTimetask.setPlanStatus("0");
			sTimetaskService.updateByPrimaryKeySelective(sTimetask);
			code = "0";
			return GiveBack.make(code, message, data);
		} catch (SchedulerException e1) {
			e1.printStackTrace();
			code = "-1";
			message = "暂停失败";
			return GiveBack.make(code, message, data);
		}
	}
	
	@SystemControllerLog(description="恢复计划")
	@RequestMapping(value = "/resumeJob", produces = "text/html;charset=UTF-8;")
	@ResponseBody
	public String resumeJob(HttpServletRequest request, HttpSession httpSession) {
		String code = "";
		String message = "";
		String data = null;

		String id = request.getParameter("id");
		STimetask sTimetask = sTimetaskService.selectByPrimaryKey(id);
		if (sTimetask == null) {
			code = "404";
			message = "未找到该任务";
			return GiveBack.make(code, message, data);
		}
		if(!"0".equals(sTimetask.getPlanStatus())&&!"1".equals(sTimetask.getJobStatus())){
			code = "1";
			message = "请先加入计划";
			return GiveBack.make(code, message, data);
		}
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(sTimetask.getName(), sTimetask.getGroupName());
		try {
			scheduler.resumeJob(jobKey);
			sTimetask.setIsConcurrent(1);
			sTimetask.setPlanStatus("1");
			sTimetaskService.updateByPrimaryKeySelective(sTimetask);
			code = "0";
			return GiveBack.make(code, message, data);
		} catch (SchedulerException e1) {
			e1.printStackTrace();
			code = "-1";
			message = "恢复失败";
			return GiveBack.make(code, message, data);
		}
	}
	
	@SystemControllerLog(description="移除计划")
	@RequestMapping(value = "/removeJob", produces = "text/html;charset=UTF-8;")
	@ResponseBody
	public String removeJob(HttpServletRequest request, HttpSession httpSession) {
		String code = "";
		String message = "";
		String data = null;

		String id = request.getParameter("id");
		STimetask sTimetask = sTimetaskService.selectByPrimaryKey(id);
		if (sTimetask == null) {
			code = "404";
			message = "未找到该任务";
			return GiveBack.make(code, message, data);
		}
		if((!"0".equals(sTimetask.getPlanStatus()))&&(!"1".equals(sTimetask.getPlanStatus()))){
			code = "1";
			message = "该任务已移除";
			return GiveBack.make(code, message, data);
		}
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(sTimetask.getName(), sTimetask.getGroupName());
		try {
			scheduler.deleteJob(jobKey);
			sTimetask.setJobStatus("0");
			sTimetask.setIsConcurrent(0);
			sTimetask.setPlanStatus("-1");
			sTimetaskService.updateByPrimaryKeySelective(sTimetask);
			code = "0";
			return GiveBack.make(code, message, data);
		} catch (SchedulerException e1) {
			e1.printStackTrace();
			code = "-1";
			message = "移除失败";
			return GiveBack.make(code, message, data);
		}
	}

	
	@RequestMapping(value = "/getJob", produces = "text/html;charset=UTF-8;")
	@ResponseBody
	public String getJob(HttpServletRequest request, HttpSession httpSession) throws SchedulerException {
		String code = "";
		String message = "";
		String data = null;

		try {
			Scheduler scheduler = schedulerFactoryBean.getScheduler();
		    GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
		    Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
		    List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
		    for (JobKey jobKey : jobKeys) {
		    	List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
		    	for (Trigger trigger : triggers) {
			        ScheduleJob job = new ScheduleJob();
			        job.setJobId(trigger.getDescription());//description 放的是job的id
			        job.setJobName(jobKey.getName());
			        job.setJobGroup(jobKey.getGroup());
			        job.setDescription("触发器:" + trigger.getKey());
			        Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
			        job.setJobStatus(triggerState.name());
			        if (trigger instanceof CronTrigger) {
			          CronTrigger cronTrigger = (CronTrigger) trigger;
			          String cronExpression = cronTrigger.getCronExpression();
			          job.setCronExpression(cronExpression);
			        }
			        jobList.add(job);
			      }
		    }
		    
		    if(jobList.size() == 0){
		    	data = "";
		    }else{
		    	data = ObjToJson.JSONPut(jobList).toJSONString();
		    }
		    code="0";
			return GiveBack.make(code, message, data);
		} catch (Exception e) {
			code = "-1";
			message = "系统异常";
			return GiveBack.make(code, message, data);
		}
	}
	
	
}

这里执行的类和方法我写的比较死,当然可以改活.

查看执行日志:

@Controller
@RequestMapping(value = "/admin/task")
public class TimetaskLogController {
	static Logger logger = Logger.getLogger(TimetaskLogController.class);
	@Autowired
	STimetaskLogService sTimetaskLogService;
	@Autowired
	STimetaskService sTimetaskService;
	@RequestMapping(value = "/getLog", produces = "text/html;charset=UTF-8;")
	@ResponseBody
	public String getLog(HttpServletRequest request, HttpSession httpSession) {
		String code = "";
		String message = "";
		String data = null;
		String pageNumStr = request.getParameter("pageNum");
		String pageSizeStr = request.getParameter("pageSize");
		int pageNum = 0;
		int pageSize = 0;
		try {
			pageNum = Integer.parseInt(pageNumStr);
			pageSize = Integer.parseInt(pageSizeStr);
		} catch (Exception e) {
			code = "100";
			message = "类型转换异常";
			return GiveBack.make(code, message, data);
		}
		try {
			STimetaskLogExample example = new STimetaskLogExample();
			example.setOrderByClause("create_date desc");
			Page<STimetaskLog> page = sTimetaskLogService.pageSelectByExample(example, pageNum, pageSize);
			List<STimetaskLog> list =  page.subList(0, page.size());
			JSONObject json = new JSONObject();
			json.put("pages",page.getPages());
			json.put("totals",page.getTotal());
			message = json.toString();
			JSONArray arr = new JSONArray();
			if(list.size() == 0){
				data = "";
			}else{
				for (int i = 0; i < list.size(); i++) {
					JSONObject json2 = new JSONObject();
					STimetaskLog s = list.get(i);
					json2.put("createDate", s.getCreateDate().toLocaleString());
					json2.put("name", sTimetaskService.selectByPrimaryKey(s.getJobId()).getName());
					json2.put("result", s.getState());
					arr.add(json2);
				}
			}
			code = "0";
			data = arr.toJSONString();
			return GiveBack.make(code, message, data);
		} catch (Exception e) {
			code = "-1";
			message = "系统异常";
			return GiveBack.make(code, message, data);
		}
	}
}

然后在spring的xml文件中加入(要在扫描其他包之后):

<!-- 初始化springUtils -->
    <bean id="springUtils" class="com.utils.base.SpringUtils" />
    <!-- 初始化Scheduler -->
    <bean id="schedulerFactoryBean"  class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
	<!-- 初始化job -->
	<bean id="initQuartzJob" class="com.utils.timetask.InitQuartzJob"  init-method="init"  lazy-init="false" />
	

前台展示:

这边可以增删改查定时任务,有个抽象的计划表,只有处于计划表的任务才是真正被执行的任务,所以有对计划表的加入/暂停/移除;

这里的cron规则我们的前端妹子扒不下来,于是干脆通过规则自己改+拼接,于是成了这样:

感觉还是可以的.......比那个怪怪的界面比较容易理解.

日志点击可查询执行结果:

前台代码就不贴了,太多了...CSS/JS啥的.

基本到这里就结束了,好了,告辞!

猜你喜欢

转载自blog.csdn.net/qq_21454973/article/details/81979660